🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / app / src / main / java / com / geeksville / mesh / service / MeshService.kt
Displaying Raw • Download
app/src/main/java/com/geeksville/mesh/service/MeshService.kt 1c3784235e7e20ed88e054097d2e7addbff92dc3 (1c378423) Text, 113.75 KB
T8b949e/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787com.geeksville.mesh.service
Tff7b72import T7ee787android.annotation.SuppressLint
Tff7b72import T7ee787android.app.Notification
Tff7b72import T7ee787android.app.Service
Tff7b72import T7ee787android.content.Context
Tff7b72import T7ee787android.content.Intent
Tff7b72import T7ee787android.content.pm.ServiceInfo
Tff7b72import T7ee787android.os.Build
Tff7b72import T7ee787android.os.IBinder
Tff7b72import T7ee787android.os.RemoteException
Tff7b72import T7ee787android.util.Log
Tff7b72import T7ee787androidx.annotation.VisibleForTesting
Tff7b72import T7ee787androidx.core.app.ServiceCompat
Tff7b72import T7ee787androidx.core.location.LocationCompat
Tff7b72import T7ee787com.geeksville.mesh.BuildConfig
Tff7b72import T7ee787com.geeksville.mesh.concurrent.handledLaunch
Tff7b72import T7ee787com.geeksville.mesh.model.NO_DEVICE_SELECTED
Tff7b72import T7ee787com.geeksville.mesh.repository.network.MQTTRepository
Tff7b72import T7ee787com.geeksville.mesh.repository.radio.InterfaceId
Tff7b72import T7ee787com.geeksville.mesh.repository.radio.RadioInterfaceService
Tff7b72import T7ee787com.geeksville.mesh.util.ignoreException
Tff7b72import T7ee787com.geeksville.mesh.util.toRemoteExceptions
Tff7b72import T7ee787com.google.protobuf.ByteString
Tff7b72import T7ee787com.google.protobuf.InvalidProtocolBufferException
Tff7b72import T7ee787com.meshtastic.core.strings.getString
Tff7b72import T7ee787dagger.Lazy
Tff7b72import T7ee787dagger.hilt.android.AndroidEntryPoint
Tff7b72import T7ee787kotlinx.coroutines.CancellationException
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.Job
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.flow.catch
Tff7b72import T7ee787kotlinx.coroutines.flow.first
Tff7b72import T7ee787kotlinx.coroutines.flow.flatMapLatest
Tff7b72import T7ee787kotlinx.coroutines.flow.flowOf
Tff7b72import T7ee787kotlinx.coroutines.flow.launchIn
Tff7b72import T7ee787kotlinx.coroutines.flow.onCompletion
Tff7b72import T7ee787kotlinx.coroutines.flow.onEach
Tff7b72import T7ee787kotlinx.coroutines.flow.onStart
Tff7b72import T7ee787org.meshtastic.core.analytics.DataPair
Tff7b72import T7ee787org.meshtastic.core.analytics.platform.PlatformAnalytics
Tff7b72import T7ee787org.meshtastic.core.common.hasLocationPermission
Tff7b72import T7ee787org.meshtastic.core.data.repository.LocationRepository
Tff7b72import T7ee787org.meshtastic.core.data.repository.MeshLogRepository
Tff7b72import T7ee787org.meshtastic.core.data.repository.NodeRepository
Tff7b72import T7ee787org.meshtastic.core.data.repository.PacketRepository
Tff7b72import T7ee787org.meshtastic.core.data.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.core.database.DatabaseManager
Tff7b72import T7ee787org.meshtastic.core.database.entity.MeshLog
Tff7b72import T7ee787org.meshtastic.core.database.entity.MetadataEntity
Tff7b72import T7ee787org.meshtastic.core.database.entity.MyNodeEntity
Tff7b72import T7ee787org.meshtastic.core.database.entity.NodeEntity
Tff7b72import T7ee787org.meshtastic.core.database.entity.Packet
Tff7b72import T7ee787org.meshtastic.core.database.entity.ReactionEntity
Tff7b72import T7ee787org.meshtastic.core.database.model.Node
Tff7b72import T7ee787org.meshtastic.core.di.CoroutineDispatchers
Tff7b72import T7ee787org.meshtastic.core.model.DataPacket
Tff7b72import T7ee787org.meshtastic.core.model.DeviceVersion
Tff7b72import T7ee787org.meshtastic.core.model.MeshUser
Tff7b72import T7ee787org.meshtastic.core.model.MessageStatus
Tff7b72import T7ee787org.meshtastic.core.model.MyNodeInfo
Tff7b72import T7ee787org.meshtastic.core.model.NodeInfo
Tff7b72import T7ee787org.meshtastic.core.model.Position
Tff7b72import T7ee787org.meshtastic.core.model.getFullTracerouteResponse
Tff7b72import T7ee787org.meshtastic.core.model.util.anonymize
Tff7b72import T7ee787org.meshtastic.core.model.util.toOneLineString
Tff7b72import T7ee787org.meshtastic.core.model.util.toPIIString
Tff7b72import T7ee787org.meshtastic.core.prefs.mesh.MeshPrefs
Tff7b72import T7ee787org.meshtastic.core.prefs.ui.UiPrefs
Tff7b72import T7ee787org.meshtastic.core.service.ConnectionState
Tff7b72import T7ee787org.meshtastic.core.service.IMeshService
Tff7b72import T7ee787org.meshtastic.core.service.MeshServiceNotifications
Tff7b72import T7ee787org.meshtastic.core.service.SERVICE_NOTIFY_ID
Tff7b72import T7ee787org.meshtastic.core.service.ServiceAction
Tff7b72import T7ee787org.meshtastic.core.service.ServiceRepository
Tff7b72import T7ee787org.meshtastic.core.strings.Res
Tff7b72import T7ee787org.meshtastic.core.strings.connected_count
Tff7b72import T7ee787org.meshtastic.core.strings.connecting
Tff7b72import T7ee787org.meshtastic.core.strings.critical_alert
Tff7b72import T7ee787org.meshtastic.core.strings.device_sleeping
Tff7b72import T7ee787org.meshtastic.core.strings.disconnected
Tff7b72import T7ee787org.meshtastic.core.strings.error_duty_cycle
Tff7b72import T7ee787org.meshtastic.core.strings.unknown_username
Tff7b72import T7ee787org.meshtastic.core.strings.waypoint_received
Tff7b72import T7ee787org.meshtastic.proto.AdminProtos
Tff7b72import T7ee787org.meshtastic.proto.AppOnlyProtos
Tff7b72import T7ee787org.meshtastic.proto.ChannelProtos
Tff7b72import T7ee787org.meshtastic.proto.ConfigProtos
Tff7b72import T7ee787org.meshtastic.proto.DeviceUIProtos
Tff7b72import T7ee787org.meshtastic.proto.LocalOnlyProtos.LocalConfig
Tff7b72import T7ee787org.meshtastic.proto.LocalOnlyProtos.LocalModuleConfig
Tff7b72import T7ee787org.meshtastic.proto.MeshProtos
Tff7b72import T7ee787org.meshtastic.proto.MeshProtos.FromRadio.PayloadVariantCase
Tff7b72import T7ee787org.meshtastic.proto.MeshProtos.MeshPacket
Tff7b72import T7ee787org.meshtastic.proto.MeshProtos.ToRadio
Tff7b72import T7ee787org.meshtastic.proto.ModuleConfigProtos
Tff7b72import T7ee787org.meshtastic.proto.PaxcountProtos
Tff7b72import T7ee787org.meshtastic.proto.Portnums
Tff7b72import T7ee787org.meshtastic.proto.StoreAndForwardProtos
Tff7b72import T7ee787org.meshtastic.proto.TelemetryProtos
Tff7b72import T7ee787org.meshtastic.proto.XmodemProtos
Tff7b72import T7ee787org.meshtastic.proto.copy
Tff7b72import T7ee787org.meshtastic.proto.fromRadio
Tff7b72import T7ee787org.meshtastic.proto.position
Tff7b72import T7ee787org.meshtastic.proto.telemetry
Tff7b72import T7ee787org.meshtastic.proto.user
Tff7b72import T7ee787timber.log.Timber
Tff7b72import T7ee787java.util.ArrayDeque
Tff7b72import T7ee787java.util.Locale
Tff7b72import T7ee787java.util.UUID
Tff7b72import T7ee787java.util.concurrent.ConcurrentHashMap
Tff7b72import T7ee787javax.inject.Inject
Tff7b72import T7ee787kotlin.math.absoluteValue
T8b949e/**
* Handles all the communication with android apps. Also keeps an internal model of the network state.
*
* Note: this service will go away once all clients are unbound from it. Warning: do not override toString, it causes
* infinite recursion on some androids (because contextWrapper.getResources calls to string
*/
Tf0883e@AndroidEntryPoint
Tff7b72class T56d364MeshService Tb4b4b4: Te6edf3ServiceTb4b4b4(Tb4b4b4) Tb4b4b4{
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3dispatchersTb4b4b4: Te6edf3CoroutineDispatchers
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3packetRepositoryTb4b4b4: Te6edf3LazyTff7b72<Te6edf3PacketRepositoryTff7b72>
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3meshLogRepositoryTb4b4b4: Te6edf3LazyTff7b72<Te6edf3MeshLogRepositoryTff7b72>
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3radioInterfaceServiceTb4b4b4: Te6edf3RadioInterfaceService
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3locationRepositoryTb4b4b4: Te6edf3LocationRepository
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3RadioConfigRepository
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3serviceRepositoryTb4b4b4: Te6edf3ServiceRepository
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3nodeRepositoryTb4b4b4: Te6edf3NodeRepository
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3databaseManagerTb4b4b4: Te6edf3DatabaseManager
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3mqttRepositoryTb4b4b4: Te6edf3MQTTRepository
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3serviceNotificationsTb4b4b4: Te6edf3MeshServiceNotifications
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3meshPrefsTb4b4b4: Te6edf3MeshPrefs
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3uiPrefsTb4b4b4: Te6edf3UiPrefs
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3connectionStateHolderTb4b4b4: Te6edf3MeshServiceConnectionStateHolder
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3packetHandlerTb4b4b4: Te6edf3PacketHandler
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3serviceBroadcastsTb4b4b4: Te6edf3MeshServiceBroadcasts
Tf0883e@Inject Tff7b72lateinit Tff7b72var Te6edf3analyticsTb4b4b4: Te6edf3PlatformAnalytics
Tff7b72private Tff7b72val Te6edf3tracerouteStartTimes Tff7b72= Te6edf3ConcurrentHashMapTff7b72<Tffa657IntTb4b4b4, Tffa657LongTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e// Intents broadcast by MeshService
Tff7b72private Tff7b72fun Td2a8ffactionReceivedTb4b4b4(Te6edf3portNumTb4b4b4: Tffa657StringTb4b4b4) Tff7b72= Ta5d6ff"Tffd700$Te6edf3prefixTa5d6ff.RECEIVED.Tffd700$Te6edf3portNumTa5d6ff"
T8b949e// generate a RECEIVED action filter string that includes either the portnumber as an int,
T8b949e// or preferably a
T8b949e// symbolic name from portnums.proto
Tff7b72fun Td2a8ffactionReceivedTb4b4b4(Te6edf3portNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657String Tb4b4b4{
Tff7b72val Te6edf3portType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3forNumberTb4b4b4(Te6edf3portNumTb4b4b4)
Tff7b72val Te6edf3portStr Tff7b72= Te6edf3portTypeTff7b72?.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72?: Te6edf3portNumTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3actionReceivedTb4b4b4(Te6edf3portStrTb4b4b4)
Tb4b4b4}
Tff7b72const Tff7b72val Te6edf3ACTION_NODE_CHANGE Tff7b72= Ta5d6ff"Tffd700$Te6edf3prefixTa5d6ff.NODE_CHANGETa5d6ff"
Tff7b72const Tff7b72val Te6edf3ACTION_MESH_CONNECTED Tff7b72= Ta5d6ff"Tffd700$Te6edf3prefixTa5d6ff.MESH_CONNECTEDTa5d6ff"
Tff7b72const Tff7b72val Te6edf3ACTION_MESSAGE_STATUS Tff7b72= Ta5d6ff"Tffd700$Te6edf3prefixTa5d6ff.MESSAGE_STATUSTa5d6ff"
Tff7b72open Tff7b72class T56d364NodeNotFoundExceptionTb4b4b4(Te6edf3reasonTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4: Te6edf3ExceptionTb4b4b4(Te6edf3reasonTb4b4b4)
Tff7b72class T56d364InvalidNodeIdExceptionTb4b4b4(Te6edf3idTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4: Te6edf3NodeNotFoundExceptionTb4b4b4(Ta5d6ff"Ta5d6ffInvalid NodeId Tffd700$Te6edf3idTa5d6ff"Tb4b4b4)
Tff7b72class T56d364NodeNumNotFoundExceptionTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4: Te6edf3NodeNotFoundExceptionTb4b4b4(Ta5d6ff"Ta5d6ffNodeNum not found Tffd700$Te6edf3idTa5d6ff"Tb4b4b4)
Tff7b72class T56d364IdNotFoundExceptionTb4b4b4(Te6edf3idTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4: Te6edf3NodeNotFoundExceptionTb4b4b4(Ta5d6ff"Ta5d6ffID not found Tffd700$Te6edf3idTa5d6ff"Tb4b4b4)
Tff7b72class T56d364NoDeviceConfigExceptionTb4b4b4(Te6edf3messageTb4b4b4: Tffa657String Tff7b72= Ta5d6ff"Ta5d6ffNo radio settings received (is our app too old?)Ta5d6ff"Tb4b4b4) Tb4b4b4:
Te6edf3RadioNotConnectedExceptionTb4b4b4(Te6edf3messageTb4b4b4)
T8b949e/**
* Talk to our running service and try to set a new device address. And then immediately call start on the
* service to possibly promote our service to be a foreground service.
*/
Tff7b72fun Td2a8ffchangeDeviceAddressTb4b4b4(Te6edf3contextTb4b4b4: Te6edf3ContextTb4b4b4, Te6edf3serviceTb4b4b4: Te6edf3IMeshServiceTb4b4b4, Te6edf3addressTb4b4b4: Tffa657String?Tb4b4b4) Tb4b4b4{
Te6edf3serviceTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Te6edf3addressTb4b4b4)
Te6edf3startServiceTb4b4b4(Te6edf3contextTb4b4b4)
Tb4b4b4}
Tff7b72fun Td2a8ffcreateIntentTb4b4b4(Te6edf3contextTb4b4b4: Te6edf3ContextTb4b4b4) Tff7b72= Te6edf3IntentTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3MeshServiceTff7b72::Te6edf3classTb4b4b4.Te6edf3javaTb4b4b4)
T8b949e/**
* The minimum firmware version we know how to talk to. We'll still be able to talk to 2.0 firmwares but only
* well enough to ask them to firmware update.
*/
Tff7b72val Te6edf3minDeviceVersion Tff7b72= Te6edf3DeviceVersionTb4b4b4(Te6edf3BuildConfigTb4b4b4.Te6edf3MIN_FW_VERSIONTb4b4b4)
Tff7b72val Te6edf3absoluteMinDeviceVersion Tff7b72= Te6edf3DeviceVersionTb4b4b4(Te6edf3BuildConfigTb4b4b4.Te6edf3ABS_MIN_FW_VERSIONTb4b4b4)
T8b949e// Two-stage config flow nonces to avoid stale BLE packets, mirroring Meshtastic-Apple
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_CONFIG_ONLY_NONCE Tff7b72= T79c0ff6T79c0ff9T79c0ff4T79c0ff2T79c0ff0
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_NODE_INFO_NONCE Tff7b72= T79c0ff6T79c0ff9T79c0ff4T79c0ff2T79c0ff1
Tff7b72private Tff7b72const Tff7b72val Te6edf3WANT_CONFIG_DELAY Tff7b72= T79c0ff1T79c0ff0T79c0ff0L
Tff7b72private Tff7b72const Tff7b72val Te6edf3HISTORY_TAG Tff7b72= Ta5d6ff"Ta5d6ffHistoryReplayTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_HISTORY_RETURN_WINDOW_MINUTES Tff7b72= T79c0ff6T79c0ff0 Tff7b72* T79c0ff2T79c0ff4
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_HISTORY_RETURN_MAX_MESSAGES Tff7b72= T79c0ff1T79c0ff0T79c0ff0
Tff7b72private Tff7b72const Tff7b72val Te6edf3MAX_EARLY_PACKET_BUFFER Tff7b72= T79c0ff1T79c0ff2T79c0ff8
Tf0883e@VisibleForTesting
Tff7b72internal Tff7b72fun Td2a8ffbuildStoreForwardHistoryRequestTb4b4b4(
Te6edf3lastRequestTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3historyReturnWindowTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3historyReturnMaxTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForward Tb4b4b4{
Tff7b72val Te6edf3historyBuilder Tff7b72= Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3HistoryTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3lastRequest Tff7b72> T79c0ff0Tb4b4b4) Te6edf3historyBuilderTb4b4b4.Te6edf3lastRequest Tff7b72= Te6edf3lastRequest
Tff7b72if Tb4b4b4(Te6edf3historyReturnWindow Tff7b72> T79c0ff0Tb4b4b4) Te6edf3historyBuilderTb4b4b4.Te6edf3window Tff7b72= Te6edf3historyReturnWindow
Tff7b72if Tb4b4b4(Te6edf3historyReturnMax Tff7b72> T79c0ff0Tb4b4b4) Te6edf3historyBuilderTb4b4b4.Te6edf3historyMessages Tff7b72= Te6edf3historyReturnMax
Tff7b72return Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setRrTb4b4b4(Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3RequestResponseTb4b4b4.Te6edf3CLIENT_HISTORYTb4b4b4)
Tb4b4b4.Te6edf3setHistoryTb4b4b4(Te6edf3historyBuilderTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tf0883e@VisibleForTesting
Tff7b72internal Tff7b72fun Td2a8ffresolveHistoryRequestParametersTb4b4b4(Te6edf3windowTb4b4b4: Tffa657IntTb4b4b4, Te6edf3maxTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3PairTff7b72<Tffa657IntTb4b4b4, Tffa657IntTff7b72> Tb4b4b4{
Tff7b72val Te6edf3resolvedWindow Tff7b72= Tff7b72if Tb4b4b4(Te6edf3window Tff7b72> T79c0ff0Tb4b4b4) Te6edf3window Tff7b72else Te6edf3DEFAULT_HISTORY_RETURN_WINDOW_MINUTES
Tff7b72val Te6edf3resolvedMax Tff7b72= Tff7b72if Tb4b4b4(Te6edf3max Tff7b72> T79c0ff0Tb4b4b4) Te6edf3max Tff7b72else Te6edf3DEFAULT_HISTORY_RETURN_MAX_MESSAGES
Tff7b72return Te6edf3resolvedWindow Te6edf3to Te6edf3resolvedMax
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3serviceJob Tff7b72= Te6edf3JobTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3serviceScope Tff7b72= Te6edf3CoroutineScopeTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3IO Tff7b72+ Te6edf3serviceJobTb4b4b4)
Tff7b72private Tff7b72inline Tff7b72fun Td2a8ffhistoryLogTb4b4b4(
Te6edf3priorityTb4b4b4: Tffa657Int Tff7b72= Te6edf3LogTb4b4b4.Te6edf3INFOTb4b4b4,
Te6edf3throwableTb4b4b4: Te6edf3Throwable? Tff7b72= Tff7b72nullTb4b4b4,
Te6edf3crossinline Te6edf3messageTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657StringTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3BuildConfigTb4b4b4.Te6edf3DEBUGTb4b4b4) Tff7b72return
Tff7b72val Te6edf3timber Tff7b72= Te6edf3TimberTb4b4b4.Te6edf3tagTb4b4b4(Te6edf3HISTORY_TAGTb4b4b4)
Tff7b72val Te6edf3msg Tff7b72= Te6edf3messageTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3throwable Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3timberTb4b4b4.Te6edf3logTb4b4b4(Te6edf3priorityTb4b4b4, Te6edf3throwableTb4b4b4, Te6edf3msgTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3timberTb4b4b4.Te6edf3logTb4b4b4(Te6edf3priorityTb4b4b4, Te6edf3msgTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffactiveDeviceAddressTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String? Tff7b72=
Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddressTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3equalsTb4b4b4(Te6edf3NO_DEVICE_SELECTEDTb4b4b4, Te6edf3ignoreCase Tff7b72= Tff7b72trueTb4b4b4) Tff7b72&Tff7b72& Tffa657itTb4b4b4.Te6edf3isNotBlankTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffcurrentTransportTb4b4b4(Te6edf3addressTb4b4b4: Tffa657String? Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddressTb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Tff7b72when Tb4b4b4(Te6edf3addressTff7b72?.Te6edf3firstOrNullTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3InterfaceIdTb4b4b4.Te6edf3BLUETOOTHTb4b4b4.Te6edf3id Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffBLETa5d6ff"
Te6edf3InterfaceIdTb4b4b4.Te6edf3TCPTb4b4b4.Te6edf3id Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffTCPTa5d6ff"
Te6edf3InterfaceIdTb4b4b4.Te6edf3SERIALTb4b4b4.Te6edf3id Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffSerialTa5d6ff"
Te6edf3InterfaceIdTb4b4b4.Te6edf3MOCKTb4b4b4.Te6edf3id Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffMockTa5d6ff"
Te6edf3InterfaceIdTb4b4b4.Te6edf3NOPTb4b4b4.Te6edf3id Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffNOPTa5d6ff"
Tff7b72else Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffUnknownTa5d6ff"
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3locationFlowTb4b4b4: Te6edf3Job? Tff7b72= Tff7b72null
Tff7b72private Tff7b72var Te6edf3mqttMessageFlowTb4b4b4: Te6edf3Job? Tff7b72= Tff7b72null
Tff7b72private Tff7b72val Te6edf3batteryPercentUnsupported Tff7b72= T79c0ff0.0
Tff7b72private Tff7b72val Te6edf3batteryPercentLowThreshold Tff7b72= T79c0ff2T79c0ff0
Tff7b72private Tff7b72val Te6edf3batteryPercentLowDivisor Tff7b72= T79c0ff5
Tff7b72private Tff7b72val Te6edf3batteryPercentCriticalThreshold Tff7b72= T79c0ff5
Tff7b72private Tff7b72val Te6edf3batteryPercentCooldownSeconds Tff7b72= T79c0ff1T79c0ff5T79c0ff0T79c0ff0
Tff7b72private Tff7b72val Te6edf3batteryPercentCooldownsTb4b4b4: Te6edf3HashMapTff7b72<Tffa657IntTb4b4b4, Tffa657LongTff7b72> Tff7b72= Te6edf3HashMapTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffgetSenderNameTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3DataPacket?Tb4b4b4)Tb4b4b4: Tffa657String Tb4b4b4{
Tff7b72val Te6edf3name Tff7b72= Te6edf3nodeDBbyIDTff7b72[Te6edf3packetTff7b72?.Te6edf3fromTff7b72]Tff7b72?.Te6edf3userTff7b72?.Te6edf3longName
Tff7b72return Te6edf3name Tff7b72?: Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3unknown_usernameTb4b4b4)
Tb4b4b4}
T8b949e/** start our location requests (if they weren't already running) */
Tff7b72private Tff7b72fun Td2a8ffstartLocationRequestsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// If we're already observing updates, don't register again
Tff7b72if Tb4b4b4(Te6edf3locationFlowTff7b72?.Te6edf3isActive Tff7b72=Tff7b72= Tff7b72trueTb4b4b4) Tff7b72return
Tf0883e@SuppressLintTb4b4b4(Ta5d6ff"Ta5d6ffMissingPermissionTa5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3hasLocationPermissionTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3locationFlow Tff7b72=
Te6edf3locationRepository
Tb4b4b4.Te6edf3getLocationsTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3location Tff7b72-Tff7b72>
Te6edf3sendPositionTb4b4b4(
Te6edf3position Tb4b4b4{
Te6edf3latitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3locationTb4b4b4.Te6edf3latitudeTb4b4b4)
Te6edf3longitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3locationTb4b4b4.Te6edf3longitudeTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3LocationCompatTb4b4b4.Te6edf3hasMslAltitudeTb4b4b4(Te6edf3locationTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3altitude Tff7b72= Te6edf3LocationCompatTb4b4b4.Te6edf3getMslAltitudeMetersTb4b4b4(Te6edf3locationTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3altitudeHae Tff7b72= Te6edf3locationTb4b4b4.Te6edf3altitudeTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3time Tff7b72= Tb4b4b4(Te6edf3locationTb4b4b4.Te6edf3time Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3groundSpeed Tff7b72= Te6edf3locationTb4b4b4.Te6edf3speedTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3groundTrack Tff7b72= Te6edf3locationTb4b4b4.Te6edf3bearingTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3locationSource Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3PositionTb4b4b4.Te6edf3LocSourceTb4b4b4.Te6edf3LOC_EXTERNAL
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffstopLocationRequestsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3locationFlowTff7b72?.Te6edf3isActive Tff7b72=Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffStopping location requestsTa5d6ff"Tb4b4b4)
Te6edf3locationFlowTff7b72?.Te6edf3cancelTb4b4b4(Tb4b4b4)
Te6edf3locationFlow Tff7b72= Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffshowAlertNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3dataPacketTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Te6edf3serviceNotificationsTb4b4b4.Te6edf3showAlertNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4,
Te6edf3getSenderNameTb4b4b4(Te6edf3dataPacketTb4b4b4)Tb4b4b4,
Te6edf3dataPacketTb4b4b4.Te6edf3alert Tff7b72?: Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3critical_alertTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffupdateMessageNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3dataPacketTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3messageTb4b4b4: Tffa657String Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3dataPacketTb4b4b4.Te6edf3dataTypeTb4b4b4) Tb4b4b4{
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUE Tff7b72-Tff7b72> Te6edf3dataPacketTb4b4b4.Te6edf3textTff7b72!!
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3WAYPOINT_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3waypoint_receivedTb4b4b4, Te6edf3dataPacketTb4b4b4.Te6edf3waypointTff7b72!!Tb4b4b4.Te6edf3nameTb4b4b4)
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tff7b72return
Tb4b4b4}
Te6edf3serviceNotificationsTb4b4b4.Te6edf3updateMessageNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4,
Te6edf3getSenderNameTb4b4b4(Te6edf3dataPacketTb4b4b4)Tb4b4b4,
Te6edf3messageTb4b4b4,
Te6edf3isBroadcast Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3to Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffonCreateTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72superTb4b4b4.Te6edf3onCreateTb4b4b4(Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffCreating mesh serviceTa5d6ff"Tb4b4b4)
Te6edf3serviceNotificationsTb4b4b4.Te6edf3initChannelsTb4b4b4(Tb4b4b4)
T8b949e// Switch to the IO thread
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3connectTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3onEachTb4b4b4(Tff7b72::Te6edf3onRadioConnectionStateTb4b4b4)Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3receivedData
Tb4b4b4.Te6edf3onStart Tb4b4b4{
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffrxCollector START transport=Tffd700${Te6edf3currentTransportTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff scope=Tffd700${Te6edf3serviceScopeTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff" Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3onCompletion Tb4b4b4{ Te6edf3cause Tff7b72-Tff7b72>
Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3WARNTb4b4b4) Tb4b4b4{
Ta5d6ff"Ta5d6ffrxCollector STOP transport=Tffd700${Te6edf3currentTransportTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff cause=Tffd700${Te6edf3causeTff7b72?.Te6edf3message Tff7b72?: Ta5d6ff"Te6edf3completedTa5d6ff"Tffd700}Ta5d6ff"
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3onEachTb4b4b4(Tff7b72::Te6edf3onReceiveFromRadioTb4b4b4)
Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3connectionError
Tb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3error Tff7b72-Tff7b72> Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffBLE Connection Error: Tffd700${Te6edf3errorTb4b4b4.Te6edf3messageTffd700}Ta5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlowTb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3localConfig Tff7b72= Tffa657it Tb4b4b4}Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3moduleConfigFlowTb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3moduleConfig Tff7b72= Tffa657it Tb4b4b4}Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3channelSetFlowTb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3channelSet Tff7b72= Tffa657it Tb4b4b4}Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3serviceRepositoryTb4b4b4.Te6edf3serviceActionTb4b4b4.Te6edf3onEachTb4b4b4(Tff7b72::Te6edf3onServiceActionTb4b4b4)Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3myNodeInfo
Tb4b4b4.Te6edf3flatMapLatest Tb4b4b4{ Te6edf3myNodeEntity Tff7b72-Tff7b72>
T8b949e// When myNodeInfo changes, set up emissions for the "provide-location-nodeNum" pref.
Tff7b72if Tb4b4b4(Te6edf3myNodeEntity Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3flowOfTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3uiPrefsTb4b4b4.Te6edf3shouldProvideNodeLocationTb4b4b4(Te6edf3myNodeEntityTb4b4b4.Te6edf3myNodeNumTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3shouldProvideNodeLocation Tff7b72-Tff7b72>
Tff7b72if Tb4b4b4(Te6edf3shouldProvideNodeLocationTb4b4b4) Tb4b4b4{
Te6edf3startLocationRequestsTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3stopLocationRequestsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Te6edf3loadCachedNodeDBTb4b4b4(Tb4b4b4) T8b949e// Load our last known node DB
T8b949e// the rest of our init will happen once we are in radioConnection.onServiceConnected
Tb4b4b4}
T8b949e/** If someone binds to us, this will be called after on create */
Tff7b72override Tff7b72fun Td2a8ffonBindTb4b4b4(Te6edf3intentTb4b4b4: Te6edf3Intent?Tb4b4b4)Tb4b4b4: Te6edf3IBinder Tff7b72= Te6edf3binder
T8b949e/**
* Called when the service is started or restarted. This method manages the foreground state of the service.
*
* It attempts to start the service in the foreground with a notification. If `startForeground` fails, for example,
* due to a `SecurityException` on Android 13+ because the `POST_NOTIFICATIONS` permission is missing, it logs an
* error* and returns `START_NOT_STICKY` to prevent the service from becoming sticky in a broken state.
*
* If the service is not intended to be in the foreground (e.g., no device is connected), it stops the foreground
* state and returns `START_NOT_STICKY`. Otherwise, it returns `START_STICKY`.
*
* @param intent The Intent supplied to `startService(Intent)`, as modified by the system.
* @param flags Additional data about this start request.
* @param startId A unique integer representing this specific request to start.
* @return The return value indicates what semantics the system should use for the service's current started state.
* See [Service.onStartCommand] for details.
*/
Tff7b72override Tff7b72fun Td2a8ffonStartCommandTb4b4b4(Te6edf3intentTb4b4b4: Te6edf3Intent?Tb4b4b4, Te6edf3flagsTb4b4b4: Tffa657IntTb4b4b4, Te6edf3startIdTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657Int Tb4b4b4{
Tff7b72val Te6edf3a Tff7b72= Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3getBondedDeviceAddressTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3wantForeground Tff7b72= Te6edf3a Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3a Tff7b72!Tff7b72= Te6edf3NO_DEVICE_SELECTED
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffRequesting foreground service=Tffd700$Te6edf3wantForegroundTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3notification Tff7b72= Te6edf3updateServiceStatusNotificationTb4b4b4(Tb4b4b4)
Tff7b72try Tb4b4b4{
Te6edf3ServiceCompatTb4b4b4.Te6edf3startForegroundTb4b4b4(
Tff7b72thisTb4b4b4,
Te6edf3SERVICE_NOTIFY_IDTb4b4b4,
Te6edf3notificationTb4b4b4,
Tff7b72if Tb4b4b4(Te6edf3BuildTb4b4b4.Te6edf3VERSIONTb4b4b4.Te6edf3SDK_INT Tff7b72>Tff7b72= Te6edf3BuildTb4b4b4.Te6edf3VERSION_CODESTb4b4b4.Te6edf3QTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3hasLocationPermissionTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ServiceInfoTb4b4b4.Te6edf3FOREGROUND_SERVICE_TYPE_MANIFEST
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3ServiceInfoTb4b4b4.Te6edf3FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T79c0ff0 T8b949e// No specific type needed for older Android versions
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffError starting foreground serviceTa5d6ff"Tb4b4b4)
Tff7b72return Te6edf3START_NOT_STICKY
Tb4b4b4}
Tff7b72return Tff7b72if Tb4b4b4(Tff7b72!Te6edf3wantForegroundTb4b4b4) Tb4b4b4{
Te6edf3ServiceCompatTb4b4b4.Te6edf3stopForegroundTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3ServiceCompatTb4b4b4.Te6edf3STOP_FOREGROUND_REMOVETb4b4b4)
Te6edf3START_NOT_STICKY
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3START_STICKY
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffonDestroyTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffDestroying mesh serviceTa5d6ff"Tb4b4b4)
T8b949e// Make sure we aren't using the notification first
Te6edf3ServiceCompatTb4b4b4.Te6edf3stopForegroundTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3ServiceCompatTb4b4b4.Te6edf3STOP_FOREGROUND_REMOVETb4b4b4)
Tff7b72superTb4b4b4.Te6edf3onDestroyTb4b4b4(Tb4b4b4)
Te6edf3serviceJobTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)
Tb4b4b4}
T8b949e//
T8b949e// BEGINNING OF MODEL - FIXME, move elsewhere
T8b949e//
Tff7b72private Tff7b72fun Td2a8ffloadCachedNodeDBTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Te6edf3myNodeInfo Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3myNodeInfoTb4b4b4.Te6edf3value
Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3putAllTb4b4b4(Te6edf3nodeRepositoryTb4b4b4.Te6edf3getNodeDBbyNumTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4)
T8b949e// Note: we do not haveNodeDB = true because that means we've got a valid db from a real
T8b949e// device (rather than
T8b949e// this possibly stale hint)
Tb4b4b4}
T8b949e/** discard entire node db & message state - used when downloading a new db from the device */
Tff7b72private Tff7b72fun Td2a8ffdiscardNodeDBTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffDiscarding NodeDBTa5d6ff"Tb4b4b4)
Te6edf3myNodeInfo Tff7b72= Tff7b72null
Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Te6edf3haveNodeDB Tff7b72= Tff7b72false
Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3myNodeInfoTb4b4b4: Te6edf3MyNodeEntity? Tff7b72= Tff7b72null
Tff7b72private Tff7b72val Te6edf3configTotal Tff7b72by Te6edf3lazy Tb4b4b4{ Te6edf3ConfigProtosTb4b4b4.Te6edf3ConfigTb4b4b4.Te6edf3getDescriptorTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3fieldsTb4b4b4.Te6edf3size Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3moduleTotal Tff7b72by Te6edf3lazy Tb4b4b4{ Te6edf3ModuleConfigProtosTb4b4b4.Te6edf3ModuleConfigTb4b4b4.Te6edf3getDescriptorTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3fieldsTb4b4b4.Te6edf3size Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3sessionPasskeyTb4b4b4: Te6edf3ByteString Tff7b72= Te6edf3ByteStringTb4b4b4.Te6edf3EMPTY
Tff7b72private Tff7b72var Te6edf3localConfigTb4b4b4: Te6edf3LocalConfig Tff7b72= Te6edf3LocalConfigTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72var Te6edf3moduleConfigTb4b4b4: Te6edf3LocalModuleConfig Tff7b72= Te6edf3LocalModuleConfigTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72var Te6edf3channelSetTb4b4b4: Te6edf3AppOnlyProtosTb4b4b4.Te6edf3ChannelSet Tff7b72= Te6edf3AppOnlyProtosTb4b4b4.Te6edf3ChannelSetTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4)
T8b949e// True after we've done our initial node db init
Tf0883e@Volatile Tff7b72private Tff7b72var Te6edf3haveNodeDB Tff7b72= Tff7b72false
T8b949e// The database of active nodes, index is the node number
Tff7b72private Tff7b72val Te6edf3nodeDBbyNodeNum Tff7b72= Te6edf3ConcurrentHashMapTff7b72<Tffa657IntTb4b4b4, Te6edf3NodeEntityTff7b72>Tb4b4b4(Tb4b4b4)
T8b949e// The database of active nodes, index is the node user ID string
T8b949e// NOTE: some NodeInfos might be in only nodeDBbyNodeNum (because we don't yet know an ID).
Tff7b72private Tff7b72val Te6edf3nodeDBbyID
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3mapKeys Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3userTb4b4b4.Te6edf3id Tb4b4b4}
T8b949e//
T8b949e// END OF MODEL
T8b949e//
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUnusedPrivateMemberTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3deviceVersion
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3DeviceVersionTb4b4b4(Te6edf3myNodeInfoTff7b72?.Te6edf3firmwareVersion Tff7b72?: Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUnusedPrivateMemberTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3appVersion
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3BuildConfigTb4b4b4.Te6edf3VERSION_CODE
Tff7b72private Tff7b72val Te6edf3minAppVersion
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3myNodeInfoTff7b72?.Te6edf3minAppVersion Tff7b72?: T79c0ff0
T8b949e// Map a nodenum to a node, or throw an exception if not found
Tff7b72private Tff7b72fun Td2a8fftoNodeInfoTb4b4b4(Te6edf3nTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3nTff7b72] Tff7b72?: Tff7b72throw Te6edf3NodeNumNotFoundExceptionTb4b4b4(Te6edf3nTb4b4b4)
T8b949e/**
* Map a nodeNum to the nodeId string If we have a NodeInfo for this ID we prefer to return the string ID inside the
* user record. but some nodes might not have a user record at all (because not yet received), in that case, we
* return a hex version of the ID just based on the number
*/
Tff7b72private Tff7b72fun Td2a8fftoNodeIDTb4b4b4(Te6edf3nTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Tff7b72if Tb4b4b4(Te6edf3n Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3NODENUM_BROADCASTTb4b4b4) Tb4b4b4{
Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCAST
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3nTff7b72]Tff7b72?.Te6edf3userTff7b72?.Te6edf3id Tff7b72?: Te6edf3DataPacketTb4b4b4.Te6edf3nodeNumToDefaultIdTb4b4b4(Te6edf3nTb4b4b4)
Tb4b4b4}
T8b949e// given a nodeNum, return a db entry - creating if necessary
Tff7b72private Tff7b72fun Td2a8ffgetOrCreateNodeInfoTb4b4b4(Te6edf3nTb4b4b4: Tffa657IntTb4b4b4, Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4) Tff7b72= Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3getOrPutTb4b4b4(Te6edf3nTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3userId Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3nodeNumToDefaultIdTb4b4b4(Te6edf3nTb4b4b4)
Tff7b72val Te6edf3defaultUser Tff7b72= Te6edf3user Tb4b4b4{
Te6edf3id Tff7b72= Te6edf3userId
Te6edf3longName Tff7b72= Ta5d6ff"Ta5d6ffMeshtastic Tffd700${Te6edf3userIdTb4b4b4.Te6edf3takeLastTb4b4b4(Te6edf3n Tff7b72= T79c0ff4Tb4b4b4)Tffd700}Ta5d6ff"
Te6edf3shortName Tff7b72= Te6edf3userIdTb4b4b4.Te6edf3takeLastTb4b4b4(Te6edf3n Tff7b72= T79c0ff4Tb4b4b4)
Te6edf3hwModel Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3HardwareModelTb4b4b4.Te6edf3UNSET
Tb4b4b4}
Te6edf3NodeEntityTb4b4b4(Te6edf3num Tff7b72= Te6edf3nTb4b4b4, Te6edf3user Tff7b72= Te6edf3defaultUserTb4b4b4, Te6edf3longName Tff7b72= Te6edf3defaultUserTb4b4b4.Te6edf3longNameTb4b4b4, Te6edf3channel Tff7b72= Te6edf3channelTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3hexIdRegex Tff7b72= Ta5d6ff"""Ta5d6ff!([0-9A-Fa-f]+)Ta5d6ff"""Tb4b4b4.Te6edf3toRegexTb4b4b4(Tb4b4b4)
T8b949e// Map a userid to a node/ node num, or throw an exception if not found
T8b949e// We prefer to find nodes based on their assigned IDs, but if no ID has been assigned to a
T8b949e// node, we can also find
T8b949e// it based on node number
Tff7b72private Tff7b72fun Td2a8fftoNodeInfoTb4b4b4(Te6edf3idTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3NodeEntity Tb4b4b4{
T8b949e// If this is a valid hexaddr will be !null
Tff7b72val Te6edf3hexStr Tff7b72= Te6edf3hexIdRegexTb4b4b4.Te6edf3matchEntireTb4b4b4(Te6edf3idTb4b4b4)Tff7b72?.Te6edf3groupsTff7b72?.Te6edf3getTb4b4b4(T79c0ff1Tb4b4b4)Tff7b72?.Te6edf3value
Tff7b72return Te6edf3nodeDBbyIDTff7b72[Te6edf3idTff7b72]
Tff7b72?: Tff7b72when Tb4b4b4{
Te6edf3id Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_LOCAL Tff7b72-Tff7b72> Te6edf3toNodeInfoTb4b4b4(Te6edf3myNodeNumTb4b4b4)
Te6edf3hexStr Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3n Tff7b72= Te6edf3hexStrTb4b4b4.Te6edf3toLongTb4b4b4(T79c0ff1T79c0ff6Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3nTff7b72] Tff7b72?: Tff7b72throw Te6edf3IdNotFoundExceptionTb4b4b4(Te6edf3idTb4b4b4)
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tff7b72throw Te6edf3InvalidNodeIdExceptionTb4b4b4(Te6edf3idTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffgetUserNameTb4b4b4(Te6edf3numTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Te6edf3withTb4b4b4(Te6edf3nodeRepositoryTb4b4b4.Te6edf3getUserTb4b4b4(Te6edf3numTb4b4b4)Tb4b4b4) Tb4b4b4{ Ta5d6ff"Tffd700$Te6edf3longNameTa5d6ff (Tffd700$Te6edf3shortNameTa5d6ff)Ta5d6ff" Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3numNodes
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3size
T8b949e/** How many nodes are currently online (including our local node) */
Tff7b72private Tff7b72val Te6edf3numOnlineNodes
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3valuesTb4b4b4.Te6edf3count Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isOnline Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8fftoNodeNumTb4b4b4(Te6edf3idTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tff7b72when Tb4b4b4(Te6edf3idTb4b4b4) Tb4b4b4{
Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCAST Tff7b72-Tff7b72> Te6edf3DataPacketTb4b4b4.Te6edf3NODENUM_BROADCAST
Te6edf3DataPacketTb4b4b4.Te6edf3ID_LOCAL Tff7b72-Tff7b72> Te6edf3myNodeNum
Tff7b72else Tff7b72-Tff7b72> Te6edf3toNodeInfoTb4b4b4(Te6edf3idTb4b4b4)Tb4b4b4.Te6edf3num
Tb4b4b4}
T8b949e// A helper function that makes it easy to update node info objects
Tff7b72private Tff7b72inline Tff7b72fun Td2a8ffupdateNodeInfoTb4b4b4(
Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3withBroadcastTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3crossinline Te6edf3updateFnTb4b4b4: Tb4b4b4(Te6edf3NodeEntityTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3info Tff7b72= Te6edf3getOrCreateNodeInfoTb4b4b4(Te6edf3nodeNumTb4b4b4, Te6edf3channelTb4b4b4)
Te6edf3updateFnTb4b4b4(Te6edf3infoTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3haveNodeDBTb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3nodeRepositoryTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3infoTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3withBroadcastTb4b4b4) Tb4b4b4{
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastNodeChangeTb4b4b4(Te6edf3infoTb4b4b4.Te6edf3toNodeInfoTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e// My node num
Tff7b72private Tff7b72val Te6edf3myNodeNum
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3myNodeInfoTff7b72?.Te6edf3myNodeNum Tff7b72?: Tff7b72throw Te6edf3RadioNotConnectedExceptionTb4b4b4(Ta5d6ff"Ta5d6ffWe don't yet have our myNodeInfoTa5d6ff"Tb4b4b4)
T8b949e// My node ID string
Tff7b72private Tff7b72val Te6edf3myNodeID
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toNodeIDTb4b4b4(Te6edf3myNodeNumTb4b4b4)
T8b949e// Admin channel index
Tff7b72private Tff7b72val Te6edf3MeshPacketTb4b4b4.Te6edf3BuilderTb4b4b4.Te6edf3adminChannelIndexTb4b4b4: Tffa657Int
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3myNodeNum Tff7b72=Tff7b72= Te6edf3to Tff7b72-Tff7b72> T79c0ff0
Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3myNodeNumTff7b72]Tff7b72?.Te6edf3hasPKC Tff7b72=Tff7b72= Tff7b72true Tff7b72&Tff7b72& Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3toTff7b72]Tff7b72?.Te6edf3hasPKC Tff7b72=Tff7b72= Tff7b72true Tff7b72-Tff7b72>
Te6edf3DataPacketTb4b4b4.Te6edf3PKC_CHANNEL_INDEX
Tff7b72else Tff7b72-Tff7b72>
Te6edf3channelSetTb4b4b4.Te6edf3settingsListTb4b4b4.Te6edf3indexOfFirst Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3nameTb4b4b4.Te6edf3equalsTb4b4b4(Ta5d6ff"Ta5d6ffadminTa5d6ff"Tb4b4b4, Te6edf3ignoreCase Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}Tb4b4b4.Te6edf3coerceAtLeastTb4b4b4(T79c0ff0Tb4b4b4)
Tb4b4b4}
T8b949e// Generate a new mesh packet builder with our node as the sender, and the specified node num
Tff7b72private Tff7b72fun Td2a8ffnewMeshPacketToTb4b4b4(Te6edf3idNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3myNodeInfo Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3RadioNotConnectedExceptionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3from Tff7b72= T79c0ff0 T8b949e// don't add myNodeNum
Te6edf3to Tff7b72= Te6edf3idNum
Tb4b4b4}
T8b949e/**
* Generate a new mesh packet builder with our node as the sender, and the specified recipient
*
* If id is null we assume a broadcast message
*/
Tff7b72private Tff7b72fun Td2a8ffnewMeshPacketToTb4b4b4(Te6edf3idTb4b4b4: Tffa657StringTb4b4b4) Tff7b72= Te6edf3newMeshPacketToTb4b4b4(Te6edf3toNodeNumTb4b4b4(Te6edf3idTb4b4b4)Tb4b4b4)
T8b949e/** Helper to make it easy to build a subpacket in the proper protobufs */
Tff7b72private Tff7b72fun Te6edf3MeshPacketTb4b4b4.Td2a8ffBuilderTb4b4b4.Te6edf3buildMeshPacketTb4b4b4(
Te6edf3wantAckTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3idTb4b4b4: Tffa657Int Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// always assign a packet ID if we didn't already have one
Te6edf3hopLimitTb4b4b4: Tffa657Int Tff7b72= Te6edf3localConfigTb4b4b4.Te6edf3loraTb4b4b4.Te6edf3hopLimitTb4b4b4,
Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3priorityTb4b4b4: Te6edf3MeshPacketTb4b4b4.Te6edf3Priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3UNSETTb4b4b4,
Te6edf3initFnTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3DataTb4b4b4.Te6edf3BuilderTb4b4b4.Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3MeshPacket Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3wantAck Tff7b72= Te6edf3wantAck
Tff7b72thisTb4b4b4.Te6edf3id Tff7b72= Te6edf3id
Tff7b72thisTb4b4b4.Te6edf3hopLimit Tff7b72= Te6edf3hopLimit
Tff7b72thisTb4b4b4.Te6edf3priority Tff7b72= Te6edf3priority
Te6edf3decoded Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3DataTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3also Tb4b4b4{ Te6edf3initFnTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3channel Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3PKC_CHANNEL_INDEXTb4b4b4) Tb4b4b4{
Te6edf3pkiEncrypted Tff7b72= Tff7b72true
Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3toTff7b72]Tff7b72?.Te6edf3userTff7b72?.Te6edf3publicKeyTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3publicKey Tff7b72-Tff7b72> Tff7b72thisTb4b4b4.Te6edf3publicKey Tff7b72= Te6edf3publicKey Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3channel Tff7b72= Te6edf3channel
Tb4b4b4}
Tff7b72return Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}
T8b949e/** Helper to make it easy to build a subpacket in the proper protobufs */
Tff7b72private Tff7b72fun Te6edf3MeshPacketTb4b4b4.Td2a8ffBuilderTb4b4b4.Te6edf3buildAdminPacketTb4b4b4(
Te6edf3idTb4b4b4: Tffa657Int Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// always assign a packet ID if we didn't already have one
Te6edf3wantResponseTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3initFnTb4b4b4: Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3BuilderTb4b4b4.Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3MeshPacket Tff7b72=
Te6edf3buildMeshPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4, Te6edf3channel Tff7b72= Te6edf3adminChannelIndexTb4b4b4, Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3RELIABLETb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3wantResponse Tff7b72= Te6edf3wantResponse
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ADMIN_APP_VALUE
Te6edf3payload Tff7b72=
Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3also Tb4b4b4{
Te6edf3initFnTb4b4b4(Tffa657itTb4b4b4)
Tffa657itTb4b4b4.Te6edf3sessionPasskey Tff7b72= Te6edf3sessionPasskey
Tb4b4b4}
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Tb4b4b4}
T8b949e// Generate a DataPacket from a MeshPacket, or null if we didn't have enough data to do so
Tff7b72private Tff7b72fun Td2a8fftoDataPacketTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3MeshPacketTb4b4b4)Tb4b4b4: Te6edf3DataPacket? Tff7b72= Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3hasDecodedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// We never convert packets that are not DataPackets
Tff7b72null
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72val Te6edf3data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decoded
Te6edf3DataPacketTb4b4b4(
Te6edf3from Tff7b72= Te6edf3toNodeIDTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4)Tb4b4b4,
Te6edf3to Tff7b72= Te6edf3toNodeIDTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3toTb4b4b4)Tb4b4b4,
Te6edf3time Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxTime Tff7b72* T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4,
Te6edf3id Tff7b72= Te6edf3packetTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3dataTb4b4b4.Te6edf3portnumValueTb4b4b4,
Te6edf3bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3hopLimit Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopLimitTb4b4b4,
Te6edf3channel Tff7b72= Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3pkiEncryptedTb4b4b4) Te6edf3DataPacketTb4b4b4.Te6edf3PKC_CHANNEL_INDEX Tff7b72else Te6edf3packetTb4b4b4.Te6edf3channelTb4b4b4,
Te6edf3wantAck Tff7b72= Te6edf3packetTb4b4b4.Te6edf3wantAckTb4b4b4,
Te6edf3hopStart Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopStartTb4b4b4,
Te6edf3snr Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxSnrTb4b4b4,
Te6edf3rssi Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxRssiTb4b4b4,
Te6edf3replyId Tff7b72= Te6edf3dataTb4b4b4.Te6edf3replyIdTb4b4b4,
Te6edf3relayNode Tff7b72= Te6edf3packetTb4b4b4.Te6edf3relayNodeTb4b4b4,
Te6edf3viaMqtt Tff7b72= Te6edf3packetTb4b4b4.Te6edf3viaMqttTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8fftoMeshPacketTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4)Tb4b4b4: Te6edf3MeshPacket Tff7b72= Te6edf3newMeshPacketToTb4b4b4(Te6edf3pTb4b4b4.Te6edf3toTff7b72!!Tb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(
Te6edf3id Tff7b72= Te6edf3pTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3wantAck Tff7b72= Te6edf3pTb4b4b4.Te6edf3wantAckTb4b4b4,
Te6edf3hopLimit Tff7b72= Te6edf3pTb4b4b4.Te6edf3hopLimitTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3pTb4b4b4.Te6edf3channelTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3pTb4b4b4.Te6edf3dataType
Te6edf3payload Tff7b72= Te6edf3ByteStringTb4b4b4.Te6edf3copyFromTb4b4b4(Te6edf3pTb4b4b4.Te6edf3bytesTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3replyId Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3pTb4b4b4.Te6edf3replyId Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3replyId Tff7b72= Te6edf3pTb4b4b4.Te6edf3replyIdTff7b72!!
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3rememberDataType Tff7b72=
Te6edf3setOfTb4b4b4(
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4,
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ALERT_APP_VALUETb4b4b4,
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3WAYPOINT_APP_VALUETb4b4b4,
Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffrememberReactionTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3MeshPacketTb4b4b4) Tff7b72= Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Tff7b72val Te6edf3reaction Tff7b72=
Te6edf3ReactionEntityTb4b4b4(
Te6edf3replyId Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3replyIdTb4b4b4,
Te6edf3userId Tff7b72= Te6edf3toNodeIDTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4)Tb4b4b4,
Te6edf3emoji Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3payloadTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3timestamp Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3packetRepositoryTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3insertReactionTb4b4b4(Te6edf3reactionTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffrememberDataPacketTb4b4b4(Te6edf3dataPacketTb4b4b4: Te6edf3DataPacketTb4b4b4, Te6edf3updateNotificationTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dataPacketTb4b4b4.Te6edf3dataType Tff7b72!in Te6edf3rememberDataTypeTb4b4b4) Tff7b72return
Tff7b72val Te6edf3fromLocal Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3from Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_LOCAL
Tff7b72val Te6edf3toBroadcast Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3to Tff7b72=Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCAST
Tff7b72val Te6edf3contactId Tff7b72= Tff7b72if Tb4b4b4(Te6edf3fromLocal Tff7b72|Tff7b72| Te6edf3toBroadcastTb4b4b4) Te6edf3dataPacketTb4b4b4.Te6edf3to Tff7b72else Te6edf3dataPacketTb4b4b4.Te6edf3from
T8b949e// contactKey: unique contact key filter (channel)+(nodeId)
Tff7b72val Te6edf3contactKey Tff7b72= Ta5d6ff"Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3channelTffd700}Tffd700$Te6edf3contactIdTa5d6ff"
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3PacketTb4b4b4(
Te6edf3uuid Tff7b72= T79c0ff0LTb4b4b4, T8b949e// autoGenerated
Te6edf3myNodeNum Tff7b72= Te6edf3myNodeNumTb4b4b4,
Te6edf3packetId Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3port_num Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3dataTypeTb4b4b4,
Te6edf3contact_key Tff7b72= Te6edf3contactKeyTb4b4b4,
Te6edf3received_time Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3read Tff7b72= Te6edf3fromLocalTb4b4b4,
Te6edf3data Tff7b72= Te6edf3dataPacketTb4b4b4,
Te6edf3snr Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3snrTb4b4b4,
Te6edf3rssi Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3rssiTb4b4b4,
Te6edf3hopsAway Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3hopsAwayTb4b4b4,
Te6edf3replyId Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3replyId Tff7b72?: T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Te6edf3packetRepositoryTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3insertTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tff7b72val Te6edf3isMuted Tff7b72= Te6edf3getContactSettingsTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4.Te6edf3isMuted
Tff7b72if Tb4b4b4(Te6edf3packetToSaveTb4b4b4.Te6edf3port_num Tff7b72=Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ALERT_APP_VALUE Tff7b72&Tff7b72& Tff7b72!Te6edf3isMutedTb4b4b4) Tb4b4b4{
Te6edf3showAlertNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3dataPacketTb4b4b4)
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3updateNotification Tff7b72&Tff7b72& Tff7b72!Te6edf3isMutedTb4b4b4) Tb4b4b4{
Te6edf3updateMessageNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3dataPacketTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Update our model and resend as needed for a MeshPacket we just received from the radio
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedDataTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3MeshPacketTb4b4b4) Tb4b4b4{
Te6edf3myNodeInfoTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3myInfo Tff7b72-Tff7b72>
Tff7b72val Te6edf3data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decoded
Tff7b72val Te6edf3bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3fromId Tff7b72= Te6edf3toNodeIDTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4)
Tff7b72val Te6edf3dataPacket Tff7b72= Te6edf3toDataPacketTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3dataPacket Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
T8b949e// We ignore most messages that we sent
Tff7b72val Te6edf3fromUs Tff7b72= Te6edf3myInfoTb4b4b4.Te6edf3myNodeNum Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3from
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived data from Tffd700$Te6edf3fromIdTa5d6ff, portnum=Tffd700${Te6edf3dataTb4b4b4.Te6edf3portnumTffd700}Ta5d6ff Tffd700${Te6edf3bytesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff bytesTa5d6ff"Tb4b4b4)
Te6edf3dataPacketTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3RECEIVED
T8b949e// if (p.hasUser()) handleReceivedUser(fromNum, p.user)
T8b949e// We tell other apps about most message types, but some may have sensitive data, so
T8b949e// that is not shared'
Tff7b72var Te6edf3shouldBroadcast Tff7b72= Tff7b72!Te6edf3fromUs
Tff7b72when Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3portnumValueTb4b4b4) Tb4b4b4{
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3replyId Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3dataTb4b4b4.Te6edf3emoji Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived REPLY from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3dataPacketTb4b4b4)
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3replyId Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3dataTb4b4b4.Te6edf3emoji Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived EMOJI from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Te6edf3rememberReactionTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived CLEAR_TEXT from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3dataPacketTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ALERT_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived ALERT_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3dataPacketTb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3WAYPOINT_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived WAYPOINT_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3WaypointTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
T8b949e// Validate locked Waypoints from the original sender
Tff7b72if Tb4b4b4(Te6edf3uTb4b4b4.Te6edf3lockedTo Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3uTb4b4b4.Te6edf3lockedTo Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4) Tff7b72return
Te6edf3rememberDataPacketTb4b4b4(Te6edf3dataPacketTb4b4b4, Te6edf3uTb4b4b4.Te6edf3expire Tff7b72> Te6edf3currentSecondTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3POSITION_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived POSITION_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3PositionTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3wantResponse Tff7b72&Tff7b72& Te6edf3uTb4b4b4.Te6edf3latitudeI Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3uTb4b4b4.Te6edf3longitudeI Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring nop position update from position requestTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3handleReceivedPositionTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4, Te6edf3uTb4b4b4, Te6edf3dataPacketTb4b4b4.Te6edf3timeTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3NODEINFO_APP_VALUE Tff7b72-Tff7b72>
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fromUsTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived NODEINFO_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72=
Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Te6edf3copy Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3isLicensedTb4b4b4) Te6edf3clearPublicKeyTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3viaMqttTb4b4b4) Te6edf3longName Tff7b72= Ta5d6ff"Tffd700$Te6edf3longNameTa5d6ff (MQTT)Ta5d6ff"
Tb4b4b4}
Te6edf3handleReceivedUserTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4, Te6edf3uTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3channelTb4b4b4)
Tb4b4b4}
T8b949e// Handle new telemetry info
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TELEMETRY_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived TELEMETRY_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72=
Te6edf3TelemetryProtosTb4b4b4.Te6edf3TelemetryTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Te6edf3copy Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3time Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Te6edf3time Tff7b72= Tb4b4b4(Te6edf3dataPacketTb4b4b4.Te6edf3time Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3handleReceivedTelemetryTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4, Te6edf3uTb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ROUTING_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived ROUTING_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
T8b949e// We always send ACKs to other apps, because they might care about the
T8b949e// messages they sent
Te6edf3shouldBroadcast Tff7b72= Tff7b72true
Tff7b72val Te6edf3u Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3RoutingTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3uTb4b4b4.Te6edf3errorReason Tff7b72=Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3RoutingTb4b4b4.Te6edf3ErrorTb4b4b4.Te6edf3DUTY_CYCLE_LIMITTb4b4b4) Tb4b4b4{
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setErrorMessageTb4b4b4(Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3error_duty_cycleTb4b4b4)Tb4b4b4)
Tb4b4b4}
Te6edf3handleAckNakTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3requestIdTb4b4b4, Te6edf3fromIdTb4b4b4, Te6edf3uTb4b4b4.Te6edf3errorReasonValueTb4b4b4, Te6edf3dataPacketTb4b4b4.Te6edf3relayNodeTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3removeResponseTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3requestIdTb4b4b4, Te6edf3complete Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3ADMIN_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived ADMIN_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72= Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
Te6edf3handleReceivedAdminTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4, Te6edf3uTb4b4b4)
Te6edf3shouldBroadcast Tff7b72= Tff7b72false
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3PAXCOUNTER_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived PAXCOUNTER_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3p Tff7b72= Te6edf3PaxcountProtosTb4b4b4.Te6edf3PaxcountTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
Te6edf3handleReceivedPaxcounterTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4, Te6edf3pTb4b4b4)
Te6edf3shouldBroadcast Tff7b72= Tff7b72false
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3STORE_FORWARD_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived STORE_FORWARD_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72= Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3payloadTb4b4b4)
Te6edf3handleReceivedStoreAndForwardTb4b4b4(Te6edf3dataPacketTb4b4b4, Te6edf3uTb4b4b4)
Te6edf3shouldBroadcast Tff7b72= Tff7b72false
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3RANGE_TEST_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived RANGE_TEST_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3moduleConfigTb4b4b4.Te6edf3rangeTestTb4b4b4.Te6edf3enabledTb4b4b4) Tff7b72return
Tff7b72val Te6edf3u Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3dataType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3uTb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3DETECTION_SENSOR_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived DETECTION_SENSOR_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72= Te6edf3dataPacketTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3dataType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3uTb4b4b4)
Tb4b4b4}
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TRACEROUTE_APP_VALUE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived TRACEROUTE_APP from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3full Tff7b72= Te6edf3packetTb4b4b4.Te6edf3getFullTracerouteResponseTb4b4b4(Tff7b72::Te6edf3getUserNameTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3full Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3requestId Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3requestId
Tff7b72val Te6edf3start Tff7b72= Te6edf3tracerouteStartTimesTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3requestIdTb4b4b4)
Tff7b72val Te6edf3response Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3start Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3elapsedMs Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start
Tff7b72val Te6edf3seconds Tff7b72= Te6edf3elapsedMs Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0.0
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffTraceroute Tffd700$Te6edf3requestIdTa5d6ff complete in Tffd700$Te6edf3secondsTa5d6ff sTa5d6ff"Tb4b4b4)
Ta5d6ff"Tffd700$Te6edf3fullTa5d6ff\Ta5d6ffnTa5d6ff\Ta5d6ffnDuration: Tffd700${Ta5d6ff"Tff7b72%Tb4b4b4.T79c0ff1fTa5d6ff"Tb4b4b4.Te6edf3formatTb4b4b4(Te6edf3secondsTb4b4b4)Tffd700}Ta5d6ff sTa5d6ff"
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3full
Tb4b4b4}
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setTracerouteResponseTb4b4b4(Te6edf3responseTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffNo custom processing needed for Tffd700${Te6edf3dataTb4b4b4.Te6edf3portnumValueTffd700}Ta5d6ff from Tffd700$Te6edf3fromIdTa5d6ff"Tb4b4b4)
Tb4b4b4}
T8b949e// We always tell other apps when new data packets arrive
Tff7b72if Tb4b4b4(Te6edf3shouldBroadcastTb4b4b4) Tb4b4b4{
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastReceivedDataTb4b4b4(Te6edf3dataPacketTb4b4b4)
Tb4b4b4}
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffnum_data_receiveTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_data_receiveTa5d6ff"Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4)
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffdata_receiveTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_bytesTa5d6ff"Tb4b4b4, Te6edf3bytesTb4b4b4.Te6edf3sizeTb4b4b4)Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4, Te6edf3dataTb4b4b4.Te6edf3portnumValueTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedAdminTb4b4b4(Te6edf3fromNodeNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3aTb4b4b4: Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4) Tb4b4b4{
Tff7b72when Tb4b4b4(Te6edf3aTb4b4b4.Te6edf3payloadVariantCaseTb4b4b4) Tb4b4b4{
Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3GET_CONFIG_RESPONSE Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3fromNodeNum Tff7b72=Tff7b72= Te6edf3myNodeNumTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3response Tff7b72= Te6edf3aTb4b4b4.Te6edf3getConfigResponse
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffAdmin: received config Tffd700${Te6edf3responseTb4b4b4.Te6edf3payloadVariantCaseTffd700}Ta5d6ff"Tb4b4b4)
Te6edf3setLocalConfigTb4b4b4(Te6edf3responseTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3GET_CHANNEL_RESPONSE Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3fromNodeNum Tff7b72=Tff7b72= Te6edf3myNodeNumTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3mi Tff7b72= Te6edf3myNodeInfo
Tff7b72if Tb4b4b4(Te6edf3mi Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3ch Tff7b72= Te6edf3aTb4b4b4.Te6edf3getChannelResponse
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffAdmin: Received channel Tffd700${Te6edf3chTb4b4b4.Te6edf3indexTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3chTb4b4b4.Te6edf3index Tff7b72+ T79c0ff1 Tff7b72< Te6edf3miTb4b4b4.Te6edf3maxChannelsTb4b4b4) Tb4b4b4{
Te6edf3handleChannelTb4b4b4(Te6edf3chTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3GET_DEVICE_METADATA_RESPONSE Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffAdmin: received DeviceMetadata from Tffd700$Te6edf3fromNodeNumTa5d6ff"Tb4b4b4)
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Te6edf3nodeRepositoryTb4b4b4.Te6edf3insertMetadataTb4b4b4(Te6edf3MetadataEntityTb4b4b4(Te6edf3fromNodeNumTb4b4b4, Te6edf3aTb4b4b4.Te6edf3getDeviceMetadataResponseTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Ta5d6ff"Ta5d6ffNo special processing needed for Tffd700${Te6edf3aTb4b4b4.Te6edf3payloadVariantCaseTffd700}Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffAdmin: Received session_passkey from Tffd700$Te6edf3fromNodeNumTa5d6ff"Tb4b4b4)
Te6edf3sessionPasskey Tff7b72= Te6edf3aTb4b4b4.Te6edf3sessionPasskey
Tb4b4b4}
T8b949e/**
* Check if a User is a default/placeholder from firmware (node was evicted and re-created) and whether we should
* preserve existing user data instead of overwriting it.
*/
Tff7b72private Tff7b72fun Td2a8ffshouldPreserveExistingUserTb4b4b4(Te6edf3existingTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4, Te6edf3incomingTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4)Tb4b4b4: Tffa657Boolean Tb4b4b4{
Tff7b72val Te6edf3isDefaultName Tff7b72= Te6edf3incomingTb4b4b4.Te6edf3longNameTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3RegexTb4b4b4(Ta5d6ff"Ta5d6ff^Meshtastic [0-9a-fA-F]{4}$Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3isDefaultHwModel Tff7b72= Te6edf3incomingTb4b4b4.Te6edf3hwModel Tff7b72=Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3HardwareModelTb4b4b4.Te6edf3UNSET
Tff7b72val Te6edf3hasExistingUser Tff7b72= Te6edf3existingTb4b4b4.Te6edf3idTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3existingTb4b4b4.Te6edf3hwModel Tff7b72!Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3HardwareModelTb4b4b4.Te6edf3UNSET
Tff7b72return Te6edf3hasExistingUser Tff7b72&Tff7b72& Te6edf3isDefaultName Tff7b72&Tff7b72& Te6edf3isDefaultHwModel
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleSharedContactImportTb4b4b4(Te6edf3contactTb4b4b4: Te6edf3AdminProtosTb4b4b4.Te6edf3SharedContactTb4b4b4) Tb4b4b4{
Te6edf3handleReceivedUserTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3nodeNumTb4b4b4, Te6edf3contactTb4b4b4.Te6edf3userTb4b4b4, Te6edf3manuallyVerified Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}
T8b949e// Update our DB of users based on someone sending out a User subpacket
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedUserTb4b4b4(
Te6edf3fromNumTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3pTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4,
Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3manuallyVerifiedTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3updateNodeInfoTb4b4b4(Te6edf3fromNumTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3newNode Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3isUnknownUser Tff7b72&Tff7b72& Te6edf3pTb4b4b4.Te6edf3hwModel Tff7b72!Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3HardwareModelTb4b4b4.Te6edf3UNSETTb4b4b4)
T8b949e// Check if this is a default/unknown user from firmware (node was evicted and re-created)
Tff7b72val Te6edf3shouldPreserve Tff7b72= Te6edf3shouldPreserveExistingUserTb4b4b4(Tffa657itTb4b4b4.Te6edf3userTb4b4b4, Te6edf3pTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3shouldPreserveTb4b4b4) Tb4b4b4{
T8b949e// Firmware sent us a placeholder - keep all our existing user data
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(
Ta5d6ff"Ta5d6ffPreserving existing user data for node Tffd700$Te6edf3fromNumTa5d6ff: Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffkept='Tffd700${Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3longNameTffd700}Ta5d6ff' (hwModel=Tffd700${Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3hwModelTffd700}Ta5d6ff), Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffskipped default='Tffd700${Te6edf3pTb4b4b4.Te6edf3longNameTffd700}Ta5d6ff' (hwModel=UNSET)Ta5d6ff"Tb4b4b4,
Tb4b4b4)
T8b949e// Still update channel and verification status
Tffa657itTb4b4b4.Te6edf3channel Tff7b72= Te6edf3channel
Tffa657itTb4b4b4.Te6edf3manuallyVerified Tff7b72= Te6edf3manuallyVerified
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72val Te6edf3keyMatch Tff7b72= Tff7b72!Tffa657itTb4b4b4.Te6edf3hasPKC Tff7b72|Tff7b72| Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3publicKey Tff7b72=Tff7b72= Te6edf3pTb4b4b4.Te6edf3publicKey
Tffa657itTb4b4b4.Te6edf3user Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3keyMatchTb4b4b4) Tb4b4b4{
Te6edf3p
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3copy Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Ta5d6ff"Ta5d6ffPublic key mismatch from Tffd700$Te6edf3longNameTa5d6ff (Tffd700$Te6edf3shortNameTa5d6ff)Ta5d6ff"Tb4b4b4)
Te6edf3publicKey Tff7b72= Te6edf3NodeEntityTb4b4b4.Te6edf3ERROR_BYTE_STRING
Tb4b4b4}
Tb4b4b4}
Tffa657itTb4b4b4.Te6edf3longName Tff7b72= Te6edf3pTb4b4b4.Te6edf3longName
Tffa657itTb4b4b4.Te6edf3shortName Tff7b72= Te6edf3pTb4b4b4.Te6edf3shortName
Tffa657itTb4b4b4.Te6edf3channel Tff7b72= Te6edf3channel
Tffa657itTb4b4b4.Te6edf3manuallyVerified Tff7b72= Te6edf3manuallyVerified
Tff7b72if Tb4b4b4(Te6edf3newNodeTb4b4b4) Tb4b4b4{
Te6edf3serviceNotificationsTb4b4b4.Te6edf3showNewNodeSeenNotificationTb4b4b4(Tffa657itTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/**
* Update our DB of users based on someone sending out a Position subpacket
*
* @param defaultTime in msecs since 1970
*/
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedPositionTb4b4b4(
Te6edf3fromNumTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3pTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3PositionTb4b4b4,
Te6edf3defaultTimeTb4b4b4: Tffa657Long Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{
T8b949e// Nodes periodically send out position updates, but those updates might not contain a lat &
T8b949e// lon (because no GPS
T8b949e// lock)
T8b949e// We like to look at the local node to see if it has been sending out valid lat/lon, so for
T8b949e// the LOCAL node
T8b949e// (only)
T8b949e// we don't record these nop position updates
Tff7b72if Tb4b4b4(Te6edf3myNodeNum Tff7b72=Tff7b72= Te6edf3fromNum Tff7b72&Tff7b72& Te6edf3pTb4b4b4.Te6edf3latitudeI Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3pTb4b4b4.Te6edf3longitudeI Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring nop position update for the local nodeTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3updateNodeInfoTb4b4b4(Te6edf3fromNumTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3setPositionTb4b4b4(Te6edf3pTb4b4b4, Tb4b4b4(Te6edf3defaultTime Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Update our DB of users based on someone sending out a Telemetry subpacket
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedTelemetryTb4b4b4(Te6edf3fromNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3telemetryTb4b4b4: Te6edf3TelemetryProtosTb4b4b4.Te6edf3TelemetryTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3isRemote Tff7b72= Tb4b4b4(Te6edf3fromNum Tff7b72!Tff7b72= Te6edf3myNodeNumTb4b4b4)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isRemoteTb4b4b4) Tb4b4b4{
Te6edf3updateServiceStatusNotificationTb4b4b4(Te6edf3telemetry Tff7b72= Te6edf3telemetryTb4b4b4)
Tb4b4b4}
Te6edf3updateNodeInfoTb4b4b4(Te6edf3fromNumTb4b4b4) Tb4b4b4{ Te6edf3nodeEntity Tff7b72-Tff7b72>
Tff7b72when Tb4b4b4{
Te6edf3telemetryTb4b4b4.Te6edf3hasDeviceMetricsTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3nodeEntityTb4b4b4.Te6edf3deviceTelemetry Tff7b72= Te6edf3telemetry
Tff7b72if Tb4b4b4(Te6edf3fromNum Tff7b72=Tff7b72= Te6edf3myNodeNum Tff7b72|Tff7b72| Tb4b4b4(Te6edf3isRemote Tff7b72&Tff7b72& Te6edf3nodeEntityTb4b4b4.Te6edf3isFavoriteTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(
Te6edf3telemetryTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3voltage Tff7b72> Te6edf3batteryPercentUnsupported Tff7b72&Tff7b72&
Te6edf3telemetryTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3batteryLevel Tff7b72<Tff7b72= Te6edf3batteryPercentLowThreshold
Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3shouldBatteryNotificationShowTb4b4b4(Te6edf3fromNumTb4b4b4, Te6edf3telemetryTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3serviceNotificationsTb4b4b4.Te6edf3showOrUpdateLowBatteryNotificationTb4b4b4(Te6edf3nodeEntityTb4b4b4, Te6edf3isRemoteTb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3batteryPercentCooldownsTb4b4b4.Te6edf3containsKeyTb4b4b4(Te6edf3fromNumTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3batteryPercentCooldownsTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3fromNumTb4b4b4)
Tb4b4b4}
Te6edf3serviceNotificationsTb4b4b4.Te6edf3cancelLowBatteryNotificationTb4b4b4(Te6edf3nodeEntityTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3telemetryTb4b4b4.Te6edf3hasEnvironmentMetricsTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3nodeEntityTb4b4b4.Te6edf3environmentTelemetry Tff7b72= Te6edf3telemetry
Te6edf3telemetryTb4b4b4.Te6edf3hasPowerMetricsTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3nodeEntityTb4b4b4.Te6edf3powerTelemetry Tff7b72= Te6edf3telemetry
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffshouldBatteryNotificationShowTb4b4b4(Te6edf3fromNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3tTb4b4b4: Te6edf3TelemetryProtosTb4b4b4.Te6edf3TelemetryTb4b4b4)Tb4b4b4: Tffa657Boolean Tb4b4b4{
Tff7b72val Te6edf3isRemote Tff7b72= Tb4b4b4(Te6edf3fromNum Tff7b72!Tff7b72= Te6edf3myNodeNumTb4b4b4)
Tff7b72var Te6edf3shouldDisplay Tff7b72= Tff7b72false
Tff7b72var Te6edf3forceDisplay Tff7b72= Tff7b72false
Tff7b72when Tb4b4b4{
Te6edf3tTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3batteryLevel Tff7b72<Tff7b72= Te6edf3batteryPercentCriticalThreshold Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3shouldDisplay Tff7b72= Tff7b72true
Te6edf3forceDisplay Tff7b72= Tff7b72true
Tb4b4b4}
Te6edf3tTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3batteryLevel Tff7b72=Tff7b72= Te6edf3batteryPercentLowThreshold Tff7b72-Tff7b72> Te6edf3shouldDisplay Tff7b72= Tff7b72true
Te6edf3tTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3batteryLevelTb4b4b4.Te6edf3modTb4b4b4(Te6edf3batteryPercentLowDivisorTb4b4b4) Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Tff7b72!Te6edf3isRemote Tff7b72-Tff7b72> Te6edf3shouldDisplay Tff7b72= Tff7b72true
Te6edf3isRemote Tff7b72-Tff7b72> Te6edf3shouldDisplay Tff7b72= Tff7b72true
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3shouldDisplayTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3now Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3batteryPercentCooldownsTb4b4b4.Te6edf3containsKeyTb4b4b4(Te6edf3fromNumTb4b4b4)Tb4b4b4) Te6edf3batteryPercentCooldownsTff7b72[Te6edf3fromNumTff7b72] Tff7b72= T79c0ff0
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3now Tff7b72- Te6edf3batteryPercentCooldownsTff7b72[Te6edf3fromNumTff7b72]Tff7b72!!Tb4b4b4) Tff7b72>Tff7b72= Te6edf3batteryPercentCooldownSeconds Tff7b72|Tff7b72| Te6edf3forceDisplayTb4b4b4) Tb4b4b4{
Te6edf3batteryPercentCooldownsTff7b72[Te6edf3fromNumTff7b72] Tff7b72= Te6edf3now
Tff7b72return Tff7b72true
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tff7b72false
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedPaxcounterTb4b4b4(Te6edf3fromNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3pTb4b4b4: Te6edf3PaxcountProtosTb4b4b4.Te6edf3PaxcountTb4b4b4) Tb4b4b4{
Te6edf3updateNodeInfoTb4b4b4(Te6edf3fromNumTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3paxcounter Tff7b72= Te6edf3p Tb4b4b4}
Tb4b4b4}
T8b949e/**
* Ask the connected radio to replay any packets it buffered while the client was offline.
*
* Radios deliver history via the Store & Forward protocol regardless of transport, so we piggyback on that
* mechanism after BLE/Wi‑Fi reconnects.
*/
Tff7b72private Tff7b72fun Td2a8ffrequestHistoryReplayTb4b4b4(Te6edf3triggerTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3address Tff7b72= Te6edf3activeDeviceAddressTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3failure Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3address Tff7b72=Tff7b72= Tff7b72null Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffno_active_addressTa5d6ff"
Te6edf3myNodeNum Tff7b72=Tff7b72= Tff7b72null Tff7b72-Tff7b72> Ta5d6ff"Ta5d6ffno_my_nodeTa5d6ff"
Tff7b72else Tff7b72-Tff7b72> Tff7b72null
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3failure Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffrequestHistory skipped trigger=Tffd700$Te6edf3triggerTa5d6ff reason=Tffd700$Te6edf3failureTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}
Tff7b72val Te6edf3safeAddress Tff7b72= Te6edf3addressTff7b72!!
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3myNodeNumTff7b72!!
Tff7b72val Te6edf3storeForwardConfig Tff7b72= Te6edf3moduleConfigTb4b4b4.Te6edf3storeForward
Tff7b72val Te6edf3lastRequest Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3getStoreForwardLastRequestTb4b4b4(Te6edf3safeAddressTb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3windowTb4b4b4, Te6edf3maxTb4b4b4) Tff7b72=
Te6edf3resolveHistoryRequestParametersTb4b4b4(Te6edf3storeForwardConfigTb4b4b4.Te6edf3historyReturnWindowTb4b4b4, Te6edf3storeForwardConfigTb4b4b4.Te6edf3historyReturnMaxTb4b4b4)
Tff7b72val Te6edf3windowSource Tff7b72= Tff7b72if Tb4b4b4(Te6edf3storeForwardConfigTb4b4b4.Te6edf3historyReturnWindow Tff7b72> T79c0ff0Tb4b4b4) Ta5d6ff"Ta5d6ffconfigTa5d6ff" Tff7b72else Ta5d6ff"Ta5d6ffdefaultTa5d6ff"
Tff7b72val Te6edf3maxSource Tff7b72= Tff7b72if Tb4b4b4(Te6edf3storeForwardConfigTb4b4b4.Te6edf3historyReturnMax Tff7b72> T79c0ff0Tb4b4b4) Ta5d6ff"Ta5d6ffconfigTa5d6ff" Tff7b72else Ta5d6ff"Ta5d6ffdefaultTa5d6ff"
Tff7b72val Te6edf3sourceSummary Tff7b72= Ta5d6ff"Ta5d6ffwindow=Tffd700$Te6edf3windowTa5d6ff(Tffd700$Te6edf3windowSourceTa5d6ff) max=Tffd700$Te6edf3maxTa5d6ff(Tffd700$Te6edf3maxSourceTa5d6ff)Ta5d6ff"
Tff7b72val Te6edf3request Tff7b72=
Te6edf3buildStoreForwardHistoryRequestTb4b4b4(
Te6edf3lastRequest Tff7b72= Te6edf3lastRequestTb4b4b4,
Te6edf3historyReturnWindow Tff7b72= Te6edf3windowTb4b4b4,
Te6edf3historyReturnMax Tff7b72= Te6edf3maxTb4b4b4,
Tb4b4b4)
Tff7b72val Te6edf3logContext Tff7b72= Ta5d6ff"Ta5d6fftrigger=Tffd700$Te6edf3triggerTa5d6ff transport=Tffd700${Te6edf3currentTransportTb4b4b4(Te6edf3safeAddressTb4b4b4)Tffd700}Ta5d6ff addr=Tffd700$Te6edf3safeAddressTa5d6ff"
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffrequestHistory Tffd700$Te6edf3logContextTa5d6ff lastRequest=Tffd700$Te6edf3lastRequestTa5d6ff Tffd700$Te6edf3sourceSummaryTa5d6ff" Tb4b4b4}
Te6edf3runCatching Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3STORE_FORWARD_APP_VALUE
Te6edf3payload Tff7b72= Te6edf3ByteStringTb4b4b4.Te6edf3copyFromTb4b4b4(Te6edf3requestTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3onFailure Tb4b4b4{ Te6edf3ex Tff7b72-Tff7b72> Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3WARNTb4b4b4, Te6edf3exTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffrequestHistory failed Tffd700$Te6edf3logContextTa5d6ff" Tb4b4b4} Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffupdateStoreForwardLastRequestTb4b4b4(Te6edf3sourceTb4b4b4: Tffa657StringTb4b4b4, Te6edf3lastRequestTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3lastRequest Tff7b72<Tff7b72= T79c0ff0Tb4b4b4) Tff7b72return
Tff7b72val Te6edf3address Tff7b72= Te6edf3activeDeviceAddressTb4b4b4(Tb4b4b4) Tff7b72?: Tff7b72return
Tff7b72val Te6edf3current Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3getStoreForwardLastRequestTb4b4b4(Te6edf3addressTb4b4b4)
Tff7b72val Te6edf3transport Tff7b72= Te6edf3currentTransportTb4b4b4(Te6edf3addressTb4b4b4)
Tff7b72val Te6edf3logContext Tff7b72= Ta5d6ff"Ta5d6ffsource=Tffd700$Te6edf3sourceTa5d6ff transport=Tffd700$Te6edf3transportTa5d6ff address=Tffd700$Te6edf3addressTa5d6ff"
Tff7b72if Tb4b4b4(Te6edf3lastRequest Tff7b72!Tff7b72= Te6edf3currentTb4b4b4) Tb4b4b4{
Te6edf3meshPrefsTb4b4b4.Te6edf3setStoreForwardLastRequestTb4b4b4(Te6edf3addressTb4b4b4, Te6edf3lastRequestTb4b4b4)
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffhistoryMarker updated Tffd700$Te6edf3logContextTa5d6ff from=Tffd700$Te6edf3currentTa5d6ff to=Tffd700$Te6edf3lastRequestTa5d6ff" Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3DEBUGTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffhistoryMarker unchanged Tffd700$Te6edf3logContextTa5d6ff value=Tffd700$Te6edf3lastRequestTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedStoreAndForwardTb4b4b4(Te6edf3dataPacketTb4b4b4: Te6edf3DataPacketTb4b4b4, Te6edf3sTb4b4b4: Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffStoreAndForward: Tffd700${Te6edf3sTb4b4b4.Te6edf3variantCaseTffd700}Ta5d6ff Tffd700${Te6edf3sTb4b4b4.Te6edf3rrTffd700}Ta5d6ff from Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3fromTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3transport Tff7b72= Te6edf3currentTransportTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3lastRequest Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3sTb4b4b4.Te6edf3variantCase Tff7b72=Tff7b72= Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3VariantCaseTb4b4b4.Te6edf3HISTORYTb4b4b4) Tb4b4b4{
Te6edf3sTb4b4b4.Te6edf3historyTb4b4b4.Te6edf3lastRequest
Tb4b4b4} Tff7b72else Tb4b4b4{
T79c0ff0
Tb4b4b4}
Tff7b72val Te6edf3baseContext Tff7b72= Ta5d6ff"Ta5d6fftransport=Tffd700$Te6edf3transportTa5d6ff from=Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3fromTffd700}Ta5d6ff"
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffrxStoreForward Tffd700$Te6edf3baseContextTa5d6ff variant=Tffd700${Te6edf3sTb4b4b4.Te6edf3variantCaseTffd700}Ta5d6ff rr=Tffd700${Te6edf3sTb4b4b4.Te6edf3rrTffd700}Ta5d6ff lastRequest=Tffd700$Te6edf3lastRequestTa5d6ff" Tb4b4b4}
Tff7b72when Tb4b4b4(Te6edf3sTb4b4b4.Te6edf3variantCaseTb4b4b4) Tb4b4b4{
Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3VariantCaseTb4b4b4.Te6edf3STATS Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3u Tff7b72=
Te6edf3dataPacketTb4b4b4.Te6edf3copyTb4b4b4(
Te6edf3bytes Tff7b72= Te6edf3sTb4b4b4.Te6edf3statsTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4,
Tb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3uTb4b4b4)
Tb4b4b4}
Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3VariantCaseTb4b4b4.Te6edf3HISTORY Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3history Tff7b72= Te6edf3sTb4b4b4.Te6edf3history
Tff7b72val Te6edf3historySummary Tff7b72=
Ta5d6ff"Ta5d6ffrouterHistory Tffd700$Te6edf3baseContextTa5d6ff messages=Tffd700${Te6edf3historyTb4b4b4.Te6edf3historyMessagesTffd700}Ta5d6ff Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffwindow=Tffd700${Te6edf3historyTb4b4b4.Te6edf3windowTffd700}Ta5d6ff lastRequest=Tffd700${Te6edf3historyTb4b4b4.Te6edf3lastRequestTffd700}Ta5d6ff"
Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3DEBUGTb4b4b4) Tb4b4b4{ Te6edf3historySummary Tb4b4b4}
Tff7b72val Te6edf3text Tff7b72=
Ta5d6ff"""
Ta5d6ff Total messages: Tffd700${Te6edf3sTb4b4b4.Te6edf3historyTb4b4b4.Te6edf3historyMessagesTffd700}
Ta5d6ff History window: Tffd700${Te6edf3sTb4b4b4.Te6edf3historyTb4b4b4.Te6edf3window Tff7b72/ T79c0ff6T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tffd700}Ta5d6ff min
Last request: Tffd700${Te6edf3sTb4b4b4.Te6edf3historyTb4b4b4.Te6edf3lastRequestTffd700}
Ta5d6ff Ta5d6ff"""
Tb4b4b4.Te6edf3trimIndentTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3u Tff7b72=
Te6edf3dataPacketTb4b4b4.Te6edf3copyTb4b4b4(
Te6edf3bytes Tff7b72= Te6edf3textTb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4,
Tb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3uTb4b4b4)
Te6edf3updateStoreForwardLastRequestTb4b4b4(Ta5d6ff"Ta5d6ffrouter_historyTa5d6ff"Tb4b4b4, Te6edf3sTb4b4b4.Te6edf3historyTb4b4b4.Te6edf3lastRequestTb4b4b4)
Tb4b4b4}
Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3VariantCaseTb4b4b4.Te6edf3TEXT Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sTb4b4b4.Te6edf3rr Tff7b72=Tff7b72= Te6edf3StoreAndForwardProtosTb4b4b4.Te6edf3StoreAndForwardTb4b4b4.Te6edf3RequestResponseTb4b4b4.Te6edf3ROUTER_TEXT_BROADCASTTb4b4b4) Tb4b4b4{
Te6edf3dataPacketTb4b4b4.Te6edf3to Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCAST
Tb4b4b4}
Tff7b72val Te6edf3textLog Tff7b72=
Ta5d6ff"Ta5d6ffrxText Tffd700$Te6edf3baseContextTa5d6ff id=Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3idTffd700}Ta5d6ff ts=Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3timeTffd700}Ta5d6ff Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffto=Tffd700${Te6edf3dataPacketTb4b4b4.Te6edf3toTffd700}Ta5d6ff decision=rememberTa5d6ff"
Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3DEBUGTb4b4b4) Tb4b4b4{ Te6edf3textLog Tb4b4b4}
Tff7b72val Te6edf3u Tff7b72=
Te6edf3dataPacketTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3bytes Tff7b72= Te6edf3sTb4b4b4.Te6edf3textTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dataType Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUETb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3uTb4b4b4)
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3earlyReceivedPackets Tff7b72= Te6edf3ArrayDequeTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
T8b949e// If apps try to send packets when our radio is sleeping, we queue them here instead
Tff7b72private Tff7b72val Te6edf3offlineSentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3DataPacketTff7b72>Tb4b4b4(Tb4b4b4)
T8b949e// Update our model and resend as needed for a MeshPacket we just received from the radio
Tff7b72private Tff7b72fun Td2a8ffhandleReceivedMeshPacketTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3MeshPacketTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3preparedPacket Tff7b72=
Te6edf3packet
Tb4b4b4.Te6edf3toBuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3apply Tb4b4b4{
T8b949e// If the rxTime was not set by the device, update with current time
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rxTime Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Te6edf3setRxTimeTb4b4b4(Te6edf3currentSecondTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[packet]: Tffd700${Te6edf3packetTb4b4b4.Te6edf3toOneLineStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3haveNodeDBTb4b4b4) Tb4b4b4{
Te6edf3processReceivedMeshPacketTb4b4b4(Te6edf3preparedPacketTb4b4b4)
Tff7b72return
Tb4b4b4}
Tff7b72val Te6edf3queueSize Tff7b72= Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3size
Tff7b72if Tb4b4b4(Te6edf3queueSize Tff7b72>Tff7b72= Te6edf3MAX_EARLY_PACKET_BUFFERTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3dropped Tff7b72= Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3removeFirstTb4b4b4(Tb4b4b4)
Te6edf3historyLogTb4b4b4(Te6edf3LogTb4b4b4.Te6edf3WARNTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3portLabel Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3droppedTb4b4b4.Te6edf3hasDecodedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3forNumberTb4b4b4(Te6edf3droppedTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValueTb4b4b4)Tff7b72?.Te6edf3name
Tff7b72?: Te6edf3droppedTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValueTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Ta5d6ff"Ta5d6ffunknownTa5d6ff"
Tb4b4b4}
Ta5d6ff"Ta5d6ffdropEarlyPacket bufferFull size=Tffd700$Te6edf3queueSizeTa5d6ff id=Tffd700${Te6edf3droppedTb4b4b4.Te6edf3idTffd700}Ta5d6ff port=Tffd700$Te6edf3portLabelTa5d6ff"
Tb4b4b4}
Tb4b4b4}
Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3addLastTb4b4b4(Te6edf3preparedPacketTb4b4b4)
Tff7b72val Te6edf3portLabel Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3preparedPacketTb4b4b4.Te6edf3hasDecodedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3forNumberTb4b4b4(Te6edf3preparedPacketTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValueTb4b4b4)Tff7b72?.Te6edf3name
Tff7b72?: Te6edf3preparedPacketTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValueTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Ta5d6ff"Ta5d6ffunknownTa5d6ff"
Tb4b4b4}
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffqueueEarlyPacket size=Tffd700${Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff id=Tffd700${Te6edf3preparedPacketTb4b4b4.Te6edf3idTffd700}Ta5d6ff port=Tffd700$Te6edf3portLabelTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffflushEarlyReceivedPacketsTb4b4b4(Te6edf3reasonTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return
Tff7b72val Te6edf3packets Tff7b72= Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4)
Te6edf3earlyReceivedPacketsTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffreplayEarlyPackets reason=Tffd700$Te6edf3reasonTa5d6ff count=Tffd700${Te6edf3packetsTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff" Tb4b4b4}
Te6edf3packetsTb4b4b4.Te6edf3forEachTb4b4b4(Tff7b72::Te6edf3processReceivedMeshPacketTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsendNowTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3packet Tff7b72= Te6edf3toMeshPacketTb4b4b4(Te6edf3pTb4b4b4)
Te6edf3pTb4b4b4.Te6edf3time Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4) T8b949e// update time to the actual time we started sending
T8b949e// Timber.d("Sending to radio: ${packet.toPIIString()}")
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffprocessQueuedPacketsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3DataPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3offlineSentPacketsTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3p Tff7b72-Tff7b72>
Tff7b72try Tb4b4b4{
Te6edf3sendNowTb4b4b4(Te6edf3pTb4b4b4)
Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffError sending queued message:Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3offlineSentPacketsTb4b4b4.Te6edf3removeAllTb4b4b4(Te6edf3sentPacketsTb4b4b4)
Tb4b4b4}
T8b949e/** Handle an ack/nak packet by updating sent message status */
Tff7b72private Tff7b72fun Td2a8ffhandleAckNakTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3fromIdTb4b4b4: Tffa657StringTb4b4b4, Te6edf3routingErrorTb4b4b4: Tffa657IntTb4b4b4, Te6edf3relayNodeTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Tff7b72val Te6edf3isAck Tff7b72= Te6edf3routingError Tff7b72=Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3RoutingTb4b4b4.Te6edf3ErrorTb4b4b4.Te6edf3NONE_VALUE
Tff7b72val Te6edf3p Tff7b72= Te6edf3packetRepositoryTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3getPacketByIdTb4b4b4(Te6edf3requestIdTb4b4b4)
T8b949e// distinguish real ACKs coming from the intended receiver
Tff7b72val Te6edf3m Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3isAck Tff7b72&Tff7b72& Te6edf3fromId Tff7b72=Tff7b72= Te6edf3pTff7b72?.Te6edf3dataTff7b72?.Te6edf3to Tff7b72-Tff7b72> Te6edf3MessageStatusTb4b4b4.Te6edf3RECEIVED
Te6edf3isAck Tff7b72-Tff7b72> Te6edf3MessageStatusTb4b4b4.Te6edf3DELIVERED
Tff7b72else Tff7b72-Tff7b72> Te6edf3MessageStatusTb4b4b4.Te6edf3ERROR
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3p Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3pTb4b4b4.Te6edf3dataTb4b4b4.Te6edf3status Tff7b72!Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3RECEIVEDTb4b4b4) Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3dataTb4b4b4.Te6edf3status Tff7b72= Te6edf3m
Te6edf3pTb4b4b4.Te6edf3routingError Tff7b72= Te6edf3routingError
Te6edf3pTb4b4b4.Te6edf3dataTb4b4b4.Te6edf3relayNode Tff7b72= Te6edf3relayNode
Tff7b72if Tb4b4b4(Te6edf3isAckTb4b4b4) Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3dataTb4b4b4.Te6edf3relays Tff7b72+Tff7b72= T79c0ff1
Tb4b4b4}
Te6edf3packetRepositoryTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3updateTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastMessageStatusTb4b4b4(Te6edf3requestIdTb4b4b4, Te6edf3mTb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e// Update our model and resend as needed for a MeshPacket we just received from the radio
Tff7b72private Tff7b72fun Td2a8ffprocessReceivedMeshPacketTb4b4b4(Te6edf3packetTb4b4b4: Te6edf3MeshPacketTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3fromNum Tff7b72= Te6edf3packetTb4b4b4.Te6edf3from
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hasDecodedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffPacketTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3packetTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromNum Tff7b72= Te6edf3packetTb4b4b4.Te6edf3fromTb4b4b4,
Te6edf3portNum Tff7b72= Te6edf3packetTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValueTb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3packet Tff7b72= Te6edf3packet Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3emitMeshPacketTb4b4b4(Te6edf3packetTb4b4b4) Tb4b4b4}
T8b949e// Update last seen for the node that sent the packet, but also for _our node_ because
T8b949e// anytime a packet
T8b949e// passes
T8b949e// through our node on the way to the phone that means that local node is also alive in
T8b949e// the mesh
Tff7b72val Te6edf3isOtherNode Tff7b72= Te6edf3myNodeNum Tff7b72!Tff7b72= Te6edf3fromNum
Te6edf3updateNodeInfoTb4b4b4(Te6edf3myNodeNumTb4b4b4, Te6edf3withBroadcast Tff7b72= Te6edf3isOtherNodeTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3lastHeard Tff7b72= Te6edf3currentSecondTb4b4b4(Tb4b4b4) Tb4b4b4}
T8b949e// Do not generate redundant broadcasts of node change for this bookkeeping
T8b949e// updateNodeInfo call
T8b949e// because apps really only care about important updates of node state - which
T8b949e// handledReceivedData will give
T8b949e// them
Te6edf3updateNodeInfoTb4b4b4(Te6edf3fromNumTb4b4b4, Te6edf3withBroadcast Tff7b72= Tff7b72falseTb4b4b4, Te6edf3channel Tff7b72= Te6edf3packetTb4b4b4.Te6edf3channelTb4b4b4) Tb4b4b4{
T8b949e// Update our last seen based on any valid timestamps. If the device didn't provide
T8b949e// a timestamp make
T8b949e// one
Tffa657itTb4b4b4.Te6edf3lastHeard Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxTime
Tffa657itTb4b4b4.Te6edf3snr Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxSnr
Tffa657itTb4b4b4.Te6edf3rssi Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rxRssi
T8b949e// Generate our own hopsAway, comparing hopStart to hopLimit.
Tffa657itTb4b4b4.Te6edf3hopsAway Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3decodedTb4b4b4.Te6edf3portnumValue Tff7b72=Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3RANGE_TEST_APP_VALUETb4b4b4) Tb4b4b4{
T79c0ff0 T8b949e// These don't come with the .hop params, but do not propogate, so they must be 0
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopStart Tff7b72=Tff7b72= T79c0ff0 Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3hopLimit Tff7b72> Te6edf3packetTb4b4b4.Te6edf3hopStartTb4b4b4) Tb4b4b4{
Tff7b72-T79c0ff1
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3hopStart Tff7b72- Te6edf3packetTb4b4b4.Te6edf3hopLimit
Tb4b4b4}
Tb4b4b4}
Te6edf3handleReceivedDataTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffinsertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4: Te6edf3MeshLogTb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
T8b949e// Do not log, because might contain PII
T8b949e// info("insert: ${packetToSave.message_type} =
T8b949e// ${packetToSave.raw_message.toOneLineString()}")
Te6edf3meshLogRepositoryTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsetLocalConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ConfigProtosTb4b4b4.Te6edf3ConfigTb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3setLocalConfigTb4b4b4(Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsetLocalModuleConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ModuleConfigProtosTb4b4b4.Te6edf3ModuleConfigTb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3setLocalModuleConfigTb4b4b4(Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffupdateChannelSettingsTb4b4b4(Te6edf3chTb4b4b4: Te6edf3ChannelProtosTb4b4b4.Te6edf3ChannelTb4b4b4) Tff7b72=
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3updateChannelSettingsTb4b4b4(Te6edf3chTb4b4b4) Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffcurrentSecondTb4b4b4(Tb4b4b4) Tff7b72= Tb4b4b4(Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
T8b949e/** Send in analytics about mesh connection */
Tff7b72private Tff7b72fun Td2a8ffreportConnectionTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3radioModel Tff7b72= Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffradio_modelTa5d6ff"Tb4b4b4, Te6edf3myNodeInfoTff7b72?.Te6edf3model Tff7b72?: Ta5d6ff"Ta5d6ffunknownTa5d6ff"Tb4b4b4)
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(
Ta5d6ff"Ta5d6ffmesh_connectTa5d6ff"Tb4b4b4,
Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_nodesTa5d6ff"Tb4b4b4, Te6edf3numNodesTb4b4b4)Tb4b4b4,
Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_onlineTa5d6ff"Tb4b4b4, Te6edf3numOnlineNodesTb4b4b4)Tb4b4b4,
Te6edf3radioModelTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3sleepTimeoutTb4b4b4: Te6edf3Job? Tff7b72= Tff7b72null
T8b949e// msecs since 1970 we started this connection
Tff7b72private Tff7b72var Te6edf3connectTimeMsec Tff7b72= T79c0ff0L
T8b949e// Called when we gain/lose connection to our radio
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffCyclomaticComplexMethodTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffonConnectionChangedTb4b4b4(Te6edf3cTb4b4b4: Te6edf3ConnectionStateTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3value Tff7b72=Tff7b72= Te6edf3c Tff7b72&Tff7b72& Te6edf3c Tff7b72!is Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4) Tff7b72return
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffonConnectionChanged: Tffd700${Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTffd700}Ta5d6ff -> Tffd700$Te6edf3cTa5d6ff"Tb4b4b4)
T8b949e// Cancel any existing timeouts
Te6edf3sleepTimeoutTff7b72?.Te6edf3cancelTb4b4b4(Tb4b4b4)
Te6edf3sleepTimeout Tff7b72= Tff7b72null
Tff7b72when Tb4b4b4(Te6edf3cTb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connecting Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3connectionStateHolderTb4b4b4.Te6edf3setStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4)
Tb4b4b4}
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connected Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3handleConnectedTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleep Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3handleDeviceSleepTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3handleDisconnectedTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3updateServiceStatusNotificationTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleDisconnectedTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3connectionStateHolderTb4b4b4.Te6edf3setStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3DisconnectedTb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffStarting disconnectTa5d6ff"Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3stopPacketQueueTb4b4b4(Tb4b4b4)
Te6edf3stopLocationRequestsTb4b4b4(Tb4b4b4)
Te6edf3stopMqttClientProxyTb4b4b4(Tb4b4b4)
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffmesh_disconnectTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_nodesTa5d6ff"Tb4b4b4, Te6edf3numNodesTb4b4b4)Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_onlineTa5d6ff"Tb4b4b4, Te6edf3numOnlineNodesTb4b4b4)Tb4b4b4)
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffnum_nodesTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_nodesTa5d6ff"Tb4b4b4, Te6edf3numNodesTb4b4b4)Tb4b4b4)
T8b949e// broadcast an intent with our new connection state
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastConnectionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleDeviceSleepTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3connectionStateHolderTb4b4b4.Te6edf3setStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleepTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3stopPacketQueueTb4b4b4(Tb4b4b4)
Te6edf3stopLocationRequestsTb4b4b4(Tb4b4b4)
Te6edf3stopMqttClientProxyTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3connectTimeMsec Tff7b72!Tff7b72= T79c0ff0LTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3now Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)
Te6edf3connectTimeMsec Tff7b72= T79c0ff0L
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffconnected_secondsTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffconnected_secondsTa5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3now Tff7b72- Te6edf3connectTimeMsecTb4b4b4) Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0.0Tb4b4b4)Tb4b4b4)
Tb4b4b4}
T8b949e// Have our timeout fire in the appropriate number of seconds
Te6edf3sleepTimeout Tff7b72=
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Tff7b72try Tb4b4b4{
T8b949e// If we have a valid timeout, wait that long (+30 seconds) otherwise, just
T8b949e// wait 30 seconds
Tff7b72val Te6edf3timeout Tff7b72= Tb4b4b4(Te6edf3localConfigTb4b4b4.Te6edf3powerTff7b72?.Te6edf3lsSecs Tff7b72?: T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff3T79c0ff0
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffWaiting for sleeping device, timeout=Tffd700$Te6edf3timeoutTa5d6ff secsTa5d6ff"Tb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3timeout Tff7b72* T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Ta5d6ff"Ta5d6ffDevice timeout out, setting disconnectedTa5d6ff"Tb4b4b4)
Te6edf3onConnectionChangedTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3DisconnectedTb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4: Te6edf3CancellationExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffdevice sleep timeout cancelledTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e// broadcast an intent with our new connection state
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastConnectionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleConnectedTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3connectionStateHolderTb4b4b4.Te6edf3setStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4)
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastConnectionTb4b4b4(Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffStarting connectTa5d6ff"Tb4b4b4)
Te6edf3historyLog Tb4b4b4{
Tff7b72val Te6edf3address Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tff7b72?: Ta5d6ff"Ta5d6ffnullTa5d6ff"
Ta5d6ff"Ta5d6ffonReconnect transport=Tffd700${Te6edf3currentTransportTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff node=Tffd700$Te6edf3addressTa5d6ff"
Tb4b4b4}
Tff7b72try Tb4b4b4{
Te6edf3connectTimeMsec Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)
Te6edf3startConfigOnlyTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3InvalidProtocolBufferExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffInvalid protocol buffer sent by device - update device software and try againTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3RadioNotConnectedExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffLost connection to radio during init - waiting for reconnect Tffd700${Te6edf3exTb4b4b4.Te6edf3messageTffd700}Ta5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3RemoteExceptionTb4b4b4) Tb4b4b4{
Te6edf3onConnectionChangedTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleepTb4b4b4)
Tff7b72throw Te6edf3ex
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffupdateServiceStatusNotificationTb4b4b4(Te6edf3telemetryTb4b4b4: Te6edf3TelemetryProtosTb4b4b4.Te6edf3TelemetryTff7b72? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3notificationSummary Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connected Tff7b72-Tff7b72> Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3connected_countTb4b4b4)Tb4b4b4.Te6edf3formatTb4b4b4(Te6edf3numOnlineNodesTb4b4b4)
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected Tff7b72-Tff7b72> Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3disconnectedTb4b4b4)
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleep Tff7b72-Tff7b72> Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3device_sleepingTb4b4b4)
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connecting Tff7b72-Tff7b72> Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3connectingTb4b4b4)
Tb4b4b4}
Tff7b72return Te6edf3serviceNotificationsTb4b4b4.Te6edf3updateServiceStateNotificationTb4b4b4(
Te6edf3summaryString Tff7b72= Te6edf3notificationSummaryTb4b4b4,
Te6edf3telemetry Tff7b72= Te6edf3telemetryTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffonRadioConnectionStateTb4b4b4(Te6edf3newStateTb4b4b4: Te6edf3ConnectionStateTb4b4b4) Tb4b4b4{
T8b949e// Respect light sleep (lsEnabled) setting: if device reports sleep
T8b949e// but lsEnabled is false, treat as disconnected.
Tff7b72val Te6edf3isRouter Tff7b72= Te6edf3localConfigTb4b4b4.Te6edf3deviceTb4b4b4.Te6edf3role Tff7b72=Tff7b72= Te6edf3ConfigProtosTb4b4b4.Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3ROUTER
Tff7b72val Te6edf3lsEnabled Tff7b72= Te6edf3localConfigTb4b4b4.Te6edf3powerTb4b4b4.Te6edf3isPowerSaving Tff7b72|Tff7b72| Te6edf3isRouter
Tff7b72val Te6edf3effectiveState Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3newStateTb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connected Tff7b72-Tff7b72> Te6edf3ConnectionStateTb4b4b4.Te6edf3Connected
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleep Tff7b72-Tff7b72>
Tff7b72if Tb4b4b4(Te6edf3lsEnabledTb4b4b4) Tb4b4b4{
Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleep
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected
Tb4b4b4}
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connecting Tff7b72-Tff7b72> Te6edf3ConnectionStateTb4b4b4.Te6edf3Connecting
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected Tff7b72-Tff7b72> Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected
Tb4b4b4}
Te6edf3onConnectionChangedTb4b4b4(Te6edf3effectiveStateTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3packetHandlersTb4b4b4: Te6edf3MapTff7b72<Te6edf3PayloadVariantCaseTb4b4b4, Tb4b4b4(Tb4b4b4(Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadioTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4)Tff7b72> Tff7b72by Te6edf3lazy Tb4b4b4{
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3entriesTb4b4b4.Te6edf3associateWith Tb4b4b4{ Te6edf3variantTb4b4b4: Te6edf3PayloadVariantCase Tff7b72-Tff7b72>
Tff7b72when Tb4b4b4(Te6edf3variantTb4b4b4) Tb4b4b4{
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3PACKET Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleReceivedMeshPacketTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3packetTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3CONFIG_COMPLETE_ID Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleConfigCompleteTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3configCompleteIdTb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3MY_INFO Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleMyInfoTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3myInfoTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3NODE_INFO Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleNodeInfoTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3nodeInfoTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3CHANNEL Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleChannelTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3channelTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3CONFIG Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleDeviceConfigTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3configTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3MODULECONFIG Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleModuleConfigTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3moduleConfigTb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3QUEUESTATUS Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3packetHandlerTb4b4b4.Te6edf3handleQueueStatusTb4b4b4(Tb4b4b4(Te6edf3protoTb4b4b4.Te6edf3queueStatusTb4b4b4)Tb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3METADATA Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleMetadataTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3metadataTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3MQTTCLIENTPROXYMESSAGE Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleMqttProxyMessageTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3mqttClientProxyMessageTb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3DEVICEUICONFIG Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleDeviceUiConfigTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3deviceuiConfigTb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3FILEINFO Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleFileInfoTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3fileInfoTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3CLIENTNOTIFICATION Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleClientNotificationTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3clientNotificationTb4b4b4)
Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3LOG_RECORD Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleLogRecordTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3logRecordTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3REBOOTED Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72> Te6edf3handleRebootedTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3rebootedTb4b4b4) Tb4b4b4}
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3XMODEMPACKET Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3protoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadio Tff7b72-Tff7b72>
Te6edf3handleXmodemPacketTb4b4b4(Te6edf3protoTb4b4b4.Te6edf3xmodemPacketTb4b4b4)
Tb4b4b4}
T8b949e// Explicitly handle default/unwanted cases to satisfy the exhaustive `when`
Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3PAYLOADVARIANT_NOT_SET Tff7b72-Tff7b72> Tb4b4b4{ Te6edf3proto Tff7b72-Tff7b72>
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReceived variant PayloadVariantUnset: Full FromRadio proto: Tffd700${Te6edf3protoTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Te6edf3MeshProtosTb4b4b4.Td2a8ffFromRadioTb4b4b4.Te6edf3routeTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3packetHandlersTff7b72[Tff7b72thisTb4b4b4.Te6edf3payloadVariantCaseTff7b72]Tff7b72?.Te6edf3invokeTb4b4b4(Tff7b72thisTb4b4b4)
Tb4b4b4}
T8b949e/**
* Parses and routes incoming data from the radio.
*
* This function first attempts to parse the data as a `FromRadio` protobuf message. If that fails, it then tries to
* parse it as a `LogRecord` for debugging purposes.
*/
Tff7b72private Tff7b72fun Td2a8ffonReceiveFromRadioTb4b4b4(Te6edf3bytesTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
Te6edf3runCatching Tb4b4b4{ Te6edf3MeshProtosTb4b4b4.Te6edf3FromRadioTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3bytesTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3onSuccess Tb4b4b4{ Te6edf3proto Tff7b72-Tff7b72>
Tff7b72if Tb4b4b4(Te6edf3protoTb4b4b4.Te6edf3payloadVariantCase Tff7b72=Tff7b72= Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3PAYLOADVARIANT_NOT_SETTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(
Ta5d6ff"Ta5d6ffReceived FromRadio with PAYLOADVARIANT_NOT_SET. rawBytes=Tffd700${Te6edf3bytesTb4b4b4.Te6edf3toHexStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff proto=Tffd700$Te6edf3protoTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Te6edf3protoTb4b4b4.Te6edf3routeTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3onFailure Tb4b4b4{ Te6edf3primaryException Tff7b72-Tff7b72>
Te6edf3runCatching Tb4b4b4{
Tff7b72val Te6edf3logRecord Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3LogRecordTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3bytesTb4b4b4)
Te6edf3handleLogRecordTb4b4b4(Te6edf3logRecordTb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3onFailure Tb4b4b4{ Te6edf3_ Tff7b72-Tff7b72>
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(
Te6edf3primaryExceptionTb4b4b4,
Ta5d6ff"Ta5d6ffFailed to parse radio packet (len=Tffd700${Te6edf3bytesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff contents=Tffd700${Te6edf3bytesTb4b4b4.Te6edf3toHexStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff). Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffNot a valid FromRadio or LogRecord.Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/** Extension function to convert a ByteArray to a hex string for logging. Example output: "0x0a,0x1f,0x..." */
Tff7b72private Tff7b72fun Te6edf3ByteArrayTb4b4b4.Td2a8fftoHexStringTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tff7b72=
Tff7b72thisTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff,Ta5d6ff"Tb4b4b4) Tb4b4b4{ Te6edf3byte Tff7b72-Tff7b72> Tffa657StringTb4b4b4.Te6edf3formatTb4b4b4(Te6edf3LocaleTb4b4b4.Te6edf3USTb4b4b4, Ta5d6ff"Ta5d6ff0x%02xTa5d6ff"Tb4b4b4, Te6edf3byteTb4b4b4) Tb4b4b4}
T8b949e// A provisional MyNodeInfo that we will install if all of our node config downloads go okay
Tff7b72private Tff7b72var Te6edf3newMyNodeInfoTb4b4b4: Te6edf3MyNodeEntity? Tff7b72= Tff7b72null
T8b949e// provisional NodeInfos we will install if all goes well
Tff7b72private Tff7b72val Te6edf3newNodes Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3MeshProtosTb4b4b4.Te6edf3NodeInfoTff7b72>Tb4b4b4(Tb4b4b4)
T8b949e// Nonces for two-stage config flow (match Meshtastic-Apple)
Tff7b72private Tff7b72var Te6edf3configOnlyNonceTb4b4b4: Tffa657Int Tff7b72= Te6edf3DEFAULT_CONFIG_ONLY_NONCE
Tff7b72private Tff7b72var Te6edf3nodeInfoNonceTb4b4b4: Tffa657Int Tff7b72= Te6edf3DEFAULT_NODE_INFO_NONCE
Tff7b72private Tff7b72fun Td2a8ffhandleDeviceConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ConfigProtosTb4b4b4.Te6edf3ConfigTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[deviceConfig] Tffd700${Te6edf3configTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffConfig Tffd700${Te6edf3configTb4b4b4.Te6edf3payloadVariantCaseTffd700}Ta5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3configTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3config Tff7b72= Te6edf3config Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3setLocalConfigTb4b4b4(Te6edf3configTb4b4b4)
Tff7b72val Te6edf3configCount Tff7b72= Te6edf3localConfigTb4b4b4.Te6edf3allFieldsTb4b4b4.Te6edf3size
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setStatusMessageTb4b4b4(Ta5d6ff"Ta5d6ffDevice config (Tffd700$Te6edf3configCountTa5d6ff / Tffd700$Te6edf3configTotalTa5d6ff)Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleModuleConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ModuleConfigProtosTb4b4b4.Te6edf3ModuleConfigTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[moduleConfig] Tffd700${Te6edf3configTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffModuleConfig Tffd700${Te6edf3configTb4b4b4.Te6edf3payloadVariantCaseTffd700}Ta5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3configTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Te6edf3moduleConfig Tff7b72= Te6edf3config Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3setLocalModuleConfigTb4b4b4(Te6edf3configTb4b4b4)
Tff7b72val Te6edf3moduleCount Tff7b72= Te6edf3moduleConfigTb4b4b4.Te6edf3allFieldsTb4b4b4.Te6edf3size
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setStatusMessageTb4b4b4(Ta5d6ff"Ta5d6ffModule config (Tffd700$Te6edf3moduleCountTa5d6ff / Tffd700$Te6edf3moduleTotalTa5d6ff)Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleChannelTb4b4b4(Te6edf3chTb4b4b4: Te6edf3ChannelProtosTb4b4b4.Te6edf3ChannelTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[channel] Tffd700${Te6edf3chTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffChannelTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3chTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Te6edf3channel Tff7b72= Te6edf3ch Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3chTb4b4b4.Te6edf3role Tff7b72!Tff7b72= Te6edf3ChannelProtosTb4b4b4.Te6edf3ChannelTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3DISABLEDTb4b4b4) Te6edf3updateChannelSettingsTb4b4b4(Te6edf3chTb4b4b4)
Tff7b72val Te6edf3maxChannels Tff7b72= Te6edf3myNodeInfoTff7b72?.Te6edf3maxChannels Tff7b72?: T79c0ff8
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setStatusMessageTb4b4b4(Ta5d6ff"Ta5d6ffChannels (Tffd700${Te6edf3chTb4b4b4.Te6edf3index Tff7b72+ T79c0ff1Tffd700}Ta5d6ff / Tffd700$Te6edf3maxChannelsTa5d6ff)Ta5d6ff"Tb4b4b4)
Tb4b4b4}
T8b949e/** Convert a protobuf NodeInfo into our model objects and update our node DB */
Tff7b72private Tff7b72fun Td2a8ffinstallNodeInfoTb4b4b4(Te6edf3infoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3NodeInfoTb4b4b4) Tb4b4b4{
T8b949e// Just replace/add any entry
Te6edf3updateNodeInfoTb4b4b4(Te6edf3infoTb4b4b4.Te6edf3numTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3hasUserTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Check if this is a default/unknown user from firmware (node was evicted and re-created)
Tff7b72val Te6edf3shouldPreserve Tff7b72= Te6edf3shouldPreserveExistingUserTb4b4b4(Tffa657itTb4b4b4.Te6edf3userTb4b4b4, Te6edf3infoTb4b4b4.Te6edf3userTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3shouldPreserveTb4b4b4) Tb4b4b4{
T8b949e// Firmware sent us a placeholder - keep all our existing user data
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(
Ta5d6ff"Ta5d6ffPreserving existing user data for node Tffd700${Te6edf3infoTb4b4b4.Te6edf3numTffd700}Ta5d6ff: Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffkept='Tffd700${Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3longNameTffd700}Ta5d6ff' (hwModel=Tffd700${Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3hwModelTffd700}Ta5d6ff), Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffskipped default='Tffd700${Te6edf3infoTb4b4b4.Te6edf3userTb4b4b4.Te6edf3longNameTffd700}Ta5d6ff' (hwModel=UNSET)Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657itTb4b4b4.Te6edf3user Tff7b72=
Te6edf3infoTb4b4b4.Te6edf3userTb4b4b4.Te6edf3copy Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3isLicensedTb4b4b4) Te6edf3clearPublicKeyTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3viaMqttTb4b4b4) Te6edf3longName Tff7b72= Ta5d6ff"Tffd700$Te6edf3longNameTa5d6ff (MQTT)Ta5d6ff"
Tb4b4b4}
Tffa657itTb4b4b4.Te6edf3longName Tff7b72= Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3longName
Tffa657itTb4b4b4.Te6edf3shortName Tff7b72= Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3shortName
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3hasPositionTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657itTb4b4b4.Te6edf3position Tff7b72= Te6edf3infoTb4b4b4.Te6edf3position
Tffa657itTb4b4b4.Te6edf3latitude Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degDTb4b4b4(Te6edf3infoTb4b4b4.Te6edf3positionTb4b4b4.Te6edf3latitudeITb4b4b4)
Tffa657itTb4b4b4.Te6edf3longitude Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degDTb4b4b4(Te6edf3infoTb4b4b4.Te6edf3positionTb4b4b4.Te6edf3longitudeITb4b4b4)
Tb4b4b4}
Tffa657itTb4b4b4.Te6edf3lastHeard Tff7b72= Te6edf3infoTb4b4b4.Te6edf3lastHeard
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3hasDeviceMetricsTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657itTb4b4b4.Te6edf3deviceTelemetry Tff7b72= Te6edf3telemetry Tb4b4b4{ Te6edf3deviceMetrics Tff7b72= Te6edf3infoTb4b4b4.Te6edf3deviceMetrics Tb4b4b4}
Tb4b4b4}
Tffa657itTb4b4b4.Te6edf3channel Tff7b72= Te6edf3infoTb4b4b4.Te6edf3channel
Tffa657itTb4b4b4.Te6edf3viaMqtt Tff7b72= Te6edf3infoTb4b4b4.Te6edf3viaMqtt
T8b949e// hopsAway should be nullable/optional from the proto, but explicitly checking it's
T8b949e// existence first
Tffa657itTb4b4b4.Te6edf3hopsAway Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3infoTb4b4b4.Te6edf3hasHopsAwayTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3infoTb4b4b4.Te6edf3hopsAway
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72-T79c0ff1
Tb4b4b4}
Tffa657itTb4b4b4.Te6edf3isFavorite Tff7b72= Te6edf3infoTb4b4b4.Te6edf3isFavorite
Tffa657itTb4b4b4.Te6edf3isIgnored Tff7b72= Te6edf3infoTb4b4b4.Te6edf3isIgnored
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleNodeInfoTb4b4b4(Te6edf3infoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3NodeInfoTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[nodeInfo] Tffd700${Te6edf3infoTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffNodeInfoTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3infoTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Te6edf3nodeInfo Tff7b72= Te6edf3info Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3newNodesTb4b4b4.Te6edf3addTb4b4b4(Te6edf3infoTb4b4b4)
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setStatusMessageTb4b4b4(Ta5d6ff"Ta5d6ffNodes (Tffd700${Te6edf3newNodesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3rawMyNodeInfoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3MyNodeInfoTff7b72? Tff7b72= Tff7b72null
T8b949e/**
* Regenerate the myNodeInfo model. We call this twice. Once after we receive myNodeInfo from the device and again
* after we have the node DB (which might allow us a better notion of our HwModel.
*/
Tff7b72private Tff7b72fun Td2a8ffregenMyNodeInfoTb4b4b4(Te6edf3metadataTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3DeviceMetadataTff7b72? Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3DeviceMetadataTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myInfo Tff7b72= Te6edf3rawMyNodeInfo
Tff7b72if Tb4b4b4(Te6edf3myInfo Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3mi Tff7b72=
Te6edf3withTb4b4b4(Te6edf3myInfoTb4b4b4) Tb4b4b4{
Te6edf3MyNodeEntityTb4b4b4(
Te6edf3myNodeNum Tff7b72= Te6edf3myNodeNumTb4b4b4,
Te6edf3model Tff7b72=
Tff7b72when Tb4b4b4(Tff7b72val Te6edf3hwModel Tff7b72= Te6edf3metadataTff7b72?.Te6edf3hwModelTb4b4b4) Tb4b4b4{
Tff7b72nullTb4b4b4,
Te6edf3MeshProtosTb4b4b4.Te6edf3HardwareModelTb4b4b4.Te6edf3UNSETTb4b4b4,
Tff7b72-Tff7b72> Tff7b72null
Tff7b72else Tff7b72-Tff7b72> Te6edf3hwModelTb4b4b4.Te6edf3nameTb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff'_'Tb4b4b4, Ta5d6ff'-'Tb4b4b4)Tb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff'p'Tb4b4b4, Ta5d6ff'.'Tb4b4b4)Tb4b4b4.Te6edf3lowercaseTb4b4b4(Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Te6edf3firmwareVersion Tff7b72= Te6edf3metadataTff7b72?.Te6edf3firmwareVersionTb4b4b4,
Te6edf3couldUpdate Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3shouldUpdate Tff7b72= Tff7b72falseTb4b4b4, T8b949e// TODO add check after re-implementing firmware updates
Te6edf3currentPacketId Tff7b72= Te6edf3currentPacketId Te6edf3and T79c0ff0Te6edf3xffffffffLTb4b4b4,
Te6edf3messageTimeoutMsec Tff7b72= T79c0ff5 Tff7b72* T79c0ff6T79c0ff0 Tff7b72* T79c0ff1T79c0ff0T79c0ff0T79c0ff0Tb4b4b4, T8b949e// constants from current firmware code
Te6edf3minAppVersion Tff7b72= Te6edf3minAppVersionTb4b4b4,
Te6edf3maxChannels Tff7b72= T79c0ff8Tb4b4b4,
Te6edf3hasWifi Tff7b72= Te6edf3metadataTff7b72?.Te6edf3hasWifi Tff7b72=Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3deviceId Tff7b72= Te6edf3deviceIdTb4b4b4.Te6edf3toStringUtf8Tb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3metadata Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3metadata Tff7b72!Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3DeviceMetadataTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3nodeRepositoryTb4b4b4.Te6edf3insertMetadataTb4b4b4(Te6edf3MetadataEntityTb4b4b4(Te6edf3miTb4b4b4.Te6edf3myNodeNumTb4b4b4, Te6edf3metadataTb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Te6edf3newMyNodeInfo Tff7b72= Te6edf3mi
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsendAnalyticsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myInfo Tff7b72= Te6edf3rawMyNodeInfo
Tff7b72val Te6edf3mi Tff7b72= Te6edf3myNodeInfo
Tff7b72if Tb4b4b4(Te6edf3myInfo Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3mi Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
T8b949e// Track types of devices and firmware versions in use
Te6edf3analyticsTb4b4b4.Te6edf3setDeviceAttributesTb4b4b4(Te6edf3miTb4b4b4.Te6edf3firmwareVersion Tff7b72?: Ta5d6ff"Ta5d6ffunknownTa5d6ff"Tb4b4b4, Te6edf3miTb4b4b4.Te6edf3model Tff7b72?: Ta5d6ff"Ta5d6ffunknownTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/** Update MyNodeInfo (called from either new API version or the old one) */
Tff7b72private Tff7b72fun Td2a8ffhandleMyInfoTb4b4b4(Te6edf3myInfoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3MyNodeInfoTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[myInfo] Tffd700${Te6edf3myInfoTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffMyNodeInfoTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3myInfoTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3myInfo Tff7b72= Te6edf3myInfo Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3rawMyNodeInfo Tff7b72= Te6edf3myInfo
Te6edf3regenMyNodeInfoTb4b4b4(Tb4b4b4)
T8b949e// We'll need to get a new set of channels and settings now
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3clearChannelSetTb4b4b4(Tb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3clearLocalConfigTb4b4b4(Tb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3clearLocalModuleConfigTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/** Update our DeviceMetadata */
Tff7b72private Tff7b72fun Td2a8ffhandleMetadataTb4b4b4(Te6edf3metadataTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3DeviceMetadataTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[deviceMetadata] Tffd700${Te6edf3metadataTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffDeviceMetadataTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3metadataTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3metadata Tff7b72= Te6edf3metadata Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Te6edf3regenMyNodeInfoTb4b4b4(Te6edf3metadataTb4b4b4)
Tb4b4b4}
T8b949e/** Publish MqttClientProxyMessage (fromRadio) */
Tff7b72private Tff7b72fun Td2a8ffhandleMqttProxyMessageTb4b4b4(Te6edf3messageTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3MqttClientProxyMessageTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[mqttClientProxyMessage] Tffd700${Te6edf3messageTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Te6edf3withTb4b4b4(Te6edf3messageTb4b4b4) Tb4b4b4{
Tff7b72when Tb4b4b4(Te6edf3payloadVariantCaseTb4b4b4) Tb4b4b4{
Te6edf3MeshProtosTb4b4b4.Te6edf3MqttClientProxyMessageTb4b4b4.Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3TEXT Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3mqttRepositoryTb4b4b4.Te6edf3publishTb4b4b4(Te6edf3topicTb4b4b4, Te6edf3textTb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3retainedTb4b4b4)
Tb4b4b4}
Te6edf3MeshProtosTb4b4b4.Te6edf3MqttClientProxyMessageTb4b4b4.Te6edf3PayloadVariantCaseTb4b4b4.Te6edf3DATA Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3mqttRepositoryTb4b4b4.Te6edf3publishTb4b4b4(Te6edf3topicTb4b4b4, Te6edf3dataTb4b4b4.Te6edf3toByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3retainedTb4b4b4)
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleClientNotificationTb4b4b4(Te6edf3notificationTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3ClientNotificationTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[clientNotification] Tffd700${Te6edf3notificationTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setClientNotificationTb4b4b4(Te6edf3notificationTb4b4b4)
Te6edf3serviceNotificationsTb4b4b4.Te6edf3showClientNotificationTb4b4b4(Te6edf3notificationTb4b4b4)
T8b949e// if the future for the originating request is still in the queue, complete as unsuccessful
T8b949e// for now
Te6edf3packetHandlerTb4b4b4.Te6edf3removeResponseTb4b4b4(Te6edf3notificationTb4b4b4.Te6edf3replyIdTb4b4b4, Te6edf3complete Tff7b72= Tff7b72falseTb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffClientNotificationTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3notificationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3clientNotification Tff7b72= Te6edf3notification Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleFileInfoTb4b4b4(Te6edf3fileInfoTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3FileInfoTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[fileInfo] Tffd700${Te6edf3fileInfoTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffFileInfoTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3fileInfoTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3fileInfo Tff7b72= Te6edf3fileInfo Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleLogRecordTb4b4b4(Te6edf3logRecordTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3LogRecordTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[logRecord] Tffd700${Te6edf3logRecordTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffLogRecordTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3logRecordTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3logRecord Tff7b72= Te6edf3logRecord Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleRebootedTb4b4b4(Te6edf3rebootedTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[rebooted] Tffd700$Te6edf3rebootedTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffRebootedTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3rebootedTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3rebooted Tff7b72= Te6edf3rebooted Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleXmodemPacketTb4b4b4(Te6edf3xmodemPacketTb4b4b4: Te6edf3XmodemProtosTb4b4b4.Te6edf3XModemTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[xmodemPacket] Tffd700${Te6edf3xmodemPacketTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffXmodemPacketTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3xmodemPacketTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3xmodemPacket Tff7b72= Te6edf3xmodemPacket Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleDeviceUiConfigTb4b4b4(Te6edf3deviceuiConfigTb4b4b4: Te6edf3DeviceUIProtosTb4b4b4.Te6edf3DeviceUIConfigTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[deviceuiConfig] Tffd700${Te6edf3deviceuiConfigTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffDeviceUIConfigTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3deviceuiConfigTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3deviceuiConfig Tff7b72= Te6edf3deviceuiConfig Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tb4b4b4}
T8b949e/** Connect, subscribe and receive Flow of MqttClientProxyMessage (toRadio) */
Tff7b72private Tff7b72fun Td2a8ffstartMqttClientProxyTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3mqttMessageFlowTff7b72?.Te6edf3isActive Tff7b72=Tff7b72= Tff7b72trueTb4b4b4) Tff7b72return
Tff7b72if Tb4b4b4(Te6edf3moduleConfigTb4b4b4.Te6edf3mqttTb4b4b4.Te6edf3enabled Tff7b72&Tff7b72& Te6edf3moduleConfigTb4b4b4.Te6edf3mqttTb4b4b4.Te6edf3proxyToClientEnabledTb4b4b4) Tb4b4b4{
Te6edf3mqttMessageFlow Tff7b72=
Te6edf3mqttRepositoryTb4b4b4.Te6edf3proxyMessageFlow
Tb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3message Tff7b72-Tff7b72>
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3ToRadioTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3mqttClientProxyMessage Tff7b72= Te6edf3message Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3catch Tb4b4b4{ Te6edf3throwable Tff7b72-Tff7b72> Te6edf3serviceRepositoryTb4b4b4.Te6edf3setErrorMessageTb4b4b4(Ta5d6ff"Ta5d6ffMqttClientProxy failed: Tffd700$Te6edf3throwableTa5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3serviceScopeTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffstopMqttClientProxyTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3mqttMessageFlowTff7b72?.Te6edf3isActive Tff7b72=Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffStopping MqttClientProxyTa5d6ff"Tb4b4b4)
Te6edf3mqttMessageFlowTff7b72?.Te6edf3cancelTb4b4b4(Tb4b4b4)
Te6edf3mqttMessageFlow Tff7b72= Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffonHasSettingsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3processQueuedPacketsTb4b4b4(Tb4b4b4)
Te6edf3startMqttClientProxyTb4b4b4(Tb4b4b4)
Te6edf3sendAnalyticsTb4b4b4(Tb4b4b4)
Te6edf3reportConnectionTb4b4b4(Tb4b4b4)
Te6edf3historyLog Tb4b4b4{
Tff7b72val Te6edf3ports Tff7b72=
Te6edf3rememberDataTypeTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff,Ta5d6ff"Tb4b4b4) Tb4b4b4{ Te6edf3port Tff7b72-Tff7b72> Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3forNumberTb4b4b4(Te6edf3portTb4b4b4)Tff7b72?.Te6edf3name Tff7b72?: Te6edf3portTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tb4b4b4}
Ta5d6ff"Ta5d6ffsubscribePorts afterReconnect ports=Tffd700$Te6edf3portsTa5d6ff"
Tb4b4b4}
Te6edf3requestHistoryReplayTb4b4b4(Ta5d6ff"Ta5d6ffonHasSettingsTa5d6ff"Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3setTimeOnly Tff7b72= Te6edf3currentSecondTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleConfigCompleteTb4b4b4(Te6edf3configCompleteIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ff[configCompleteId]: Tffd700${Te6edf3configCompleteIdTb4b4b4.Te6edf3toPIIStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72when Tb4b4b4(Te6edf3configCompleteIdTb4b4b4) Tb4b4b4{
Te6edf3configOnlyNonce Tff7b72-Tff7b72> Te6edf3handleConfigOnlyCompleteTb4b4b4(Tb4b4b4)
Te6edf3nodeInfoNonce Tff7b72-Tff7b72> Te6edf3handleNodeInfoCompleteTb4b4b4(Tb4b4b4)
Tff7b72else Tff7b72-Tff7b72>
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(
Ta5d6ff"Ta5d6ffConfig complete id mismatch: received=Tffd700$Te6edf3configCompleteIdTa5d6ff expected one of [Tffd700$Te6edf3configOnlyNonceTa5d6ff,Tffd700$Te6edf3nodeInfoNonceTa5d6ff]Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleConfigOnlyCompleteTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffConfig-only complete for nonce Tffd700$Te6edf3configOnlyNonceTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffConfigOnlyCompleteTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3configOnlyNonceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3configCompleteId Tff7b72= Te6edf3configOnlyNonce Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3newMyNodeInfo Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffDid not receive a valid configTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3myNodeInfo Tff7b72= Te6edf3newMyNodeInfo
Tb4b4b4}
T8b949e// Keep BLE awake and allow the firmware to settle before the node-info stage.
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Te6edf3delayTb4b4b4(Te6edf3WANT_CONFIG_DELAYTb4b4b4)
Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3WANT_CONFIG_DELAYTb4b4b4)
Te6edf3startNodeInfoOnlyTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/** Send a ToRadio heartbeat to keep the link alive without producing mesh traffic. */
Tff7b72private Tff7b72fun Td2a8ffsendHeartbeatTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3ToRadioTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3heartbeat Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3HeartbeatTb4b4b4.Te6edf3getDefaultInstanceTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffHeartbeat sent between nonce stagesTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffFailed to send heartbeat; proceeding with node-info stageTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffhandleNodeInfoCompleteTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffNodeInfo complete for nonce Tffd700$Te6edf3nodeInfoNonceTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetToSave Tff7b72=
Te6edf3MeshLogTb4b4b4(
Te6edf3uuid Tff7b72= Te6edf3UUIDTb4b4b4.Te6edf3randomUUIDTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3message_type Tff7b72= Ta5d6ff"Ta5d6ffNodeInfoCompleteTa5d6ff"Tb4b4b4,
Te6edf3received_date Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3raw_message Tff7b72= Te6edf3nodeInfoNonceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3fromRadio Tff7b72= Te6edf3fromRadio Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3configCompleteId Tff7b72= Te6edf3nodeInfoNonce Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3insertMeshLogTb4b4b4(Te6edf3packetToSaveTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3newNodesTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffDid not receive a valid node infoTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3newNodesTb4b4b4.Te6edf3forEachTb4b4b4(Tff7b72::Te6edf3installNodeInfoTb4b4b4)
Te6edf3newNodesTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
T8b949e// Individual nodes are already upserted to DB via updateNodeInfo->nodeRepository.upsert
T8b949e// Only call installConfig to persist myNodeInfo, not to overwrite all nodes
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3myNodeInfoTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3nodeRepositoryTb4b4b4.Te6edf3installConfigTb4b4b4(Tffa657itTb4b4b4, Te6edf3emptyListTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Tb4b4b4}
Te6edf3haveNodeDB Tff7b72= Tff7b72true
Te6edf3flushEarlyReceivedPacketsTb4b4b4(Ta5d6ff"Ta5d6ffnode_info_completeTa5d6ff"Tb4b4b4)
Te6edf3sendAnalyticsTb4b4b4(Tb4b4b4)
Te6edf3onHasSettingsTb4b4b4(Tb4b4b4)
Te6edf3connectionStateHolderTb4b4b4.Te6edf3setStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastConnectionTb4b4b4(Tb4b4b4)
Te6edf3updateServiceStatusNotificationTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffstartConfigOnlyTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3newMyNodeInfo Tff7b72= Tff7b72null
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffStarting config-only nonce=Tffd700$Te6edf3configOnlyNonceTa5d6ff"Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3ToRadioTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3wantConfigId Tff7b72= Te6edf3configOnlyNonce Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffstartNodeInfoOnlyTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3newNodesTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffStarting node-info nonce=Tffd700$Te6edf3nodeInfoNonceTa5d6ff"Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3ToRadioTb4b4b4.Te6edf3newBuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Tff7b72thisTb4b4b4.Te6edf3wantConfigId Tff7b72= Te6edf3nodeInfoNonce Tb4b4b4}Tb4b4b4)
Tb4b4b4}
T8b949e/** Send a position (typically from our built in GPS) into the mesh. */
Tff7b72private Tff7b72fun Td2a8ffsendPositionTb4b4b4(Te6edf3positionTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3PositionTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4, Te6edf3wantResponseTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72val Te6edf3mi Tff7b72= Te6edf3myNodeInfo
Tff7b72if Tb4b4b4(Te6edf3mi Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3idNum Tff7b72= Te6edf3destNum Tff7b72?: Te6edf3miTb4b4b4.Te6edf3myNodeNum T8b949e// when null we just send to the local node
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffSending our position/time to=Tffd700$Te6edf3idNumTa5d6ff Tffd700${Te6edf3PositionTb4b4b4(Te6edf3positionTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
T8b949e// Also update our own map for our nodeNum, by handling the packet just like packets from other users
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3localConfigTb4b4b4.Te6edf3positionTb4b4b4.Te6edf3fixedPositionTb4b4b4) Tb4b4b4{
Te6edf3handleReceivedPositionTb4b4b4(Te6edf3miTb4b4b4.Te6edf3myNodeNumTb4b4b4, Te6edf3positionTb4b4b4)
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3idNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(
Te6edf3channel Tff7b72= Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) T79c0ff0 Tff7b72else Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3destNumTff7b72]Tff7b72?.Te6edf3channel Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3POSITION_APP_VALUE
Te6edf3payload Tff7b72= Te6edf3positionTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Tff7b72thisTb4b4b4.Te6edf3wantResponse Tff7b72= Te6edf3wantResponse
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4: Te6edf3BLEExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring disconnected radio during gps location updateTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/** Send setOwner admin packet with [MeshProtos.User] protobuf */
Tff7b72private Tff7b72fun Td2a8ffsetOwnerTb4b4b4(Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3userTb4b4b4: Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4) Tff7b72= Te6edf3withTb4b4b4(Te6edf3userTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3dest Tff7b72= Te6edf3nodeDBbyIDTff7b72[Te6edf3idTff7b72] Tff7b72?: Tff7b72throw Te6edf3ExceptionTb4b4b4(Ta5d6ff"Ta5d6ffCan't set user without a NodeInfoTa5d6ff"Tb4b4b4) T8b949e// this shouldn't happen
Tff7b72val Te6edf3old Tff7b72= Te6edf3destTb4b4b4.Te6edf3user
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffComplexConditionTa5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3user Tff7b72=Tff7b72= Te6edf3oldTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring nop owner changeTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(
Ta5d6ff"Ta5d6ffsetOwner Id: Tffd700$Te6edf3idTa5d6ff longName: Tffd700${Te6edf3longNameTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff shortName: Tffd700$Te6edf3shortNameTa5d6ff isLicensed: Tffd700$Te6edf3isLicensedTa5d6ff isUnmessagable: Tffd700$Te6edf3isUnmessagableTa5d6ff"Tb4b4b4,
Tb4b4b4)
T8b949e// Also update our own map for our nodeNum, by handling the packet just like packets from other users
Te6edf3handleReceivedUserTb4b4b4(Te6edf3destTb4b4b4.Te6edf3numTb4b4b4, Te6edf3userTb4b4b4)
T8b949e// encapsulate our payload in the proper protobuf and fire it off
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3destTb4b4b4.Te6edf3numTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3setOwner Tff7b72= Te6edf3user Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e// Do not use directly, instead call generatePacketId()
Tff7b72private Tff7b72var Te6edf3currentPacketId Tff7b72= Te6edf3javaTb4b4b4.Te6edf3utilTb4b4b4.Te6edf3RandomTb4b4b4(Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3nextLongTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3absoluteValue
T8b949e/** Generate a unique packet ID (if we know enough to do so - otherwise return 0 so the device will do it) */
Tf0883e@Synchronized
Tff7b72private Tff7b72fun Td2a8ffgeneratePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Int Tb4b4b4{
Tff7b72val Te6edf3numPacketIds Tff7b72= Tb4b4b4(Tb4b4b4(T79c0ff1L Te6edf3shl T79c0ff3T79c0ff2Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4)
Te6edf3currentPacketIdTff7b72+Tff7b72+
Te6edf3currentPacketId Tff7b72= Te6edf3currentPacketId Te6edf3and T79c0ff0Te6edf3xffffffff
Tff7b72return Tb4b4b4(Tb4b4b4(Te6edf3currentPacketId Tff7b72% Te6edf3numPacketIdsTb4b4b4) Tff7b72+ T79c0ff1LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffenqueueForSendingTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3dataType Tff7b72in Te6edf3rememberDataTypeTb4b4b4) Tb4b4b4{
Te6edf3offlineSentPacketsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffonServiceActionTb4b4b4(Te6edf3actionTb4b4b4: Te6edf3ServiceActionTb4b4b4) Tb4b4b4{
Te6edf3ignoreException Tb4b4b4{
Tff7b72when Tb4b4b4(Te6edf3actionTb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3GetDeviceMetadata Tff7b72-Tff7b72> Te6edf3getDeviceMetadataTb4b4b4(Te6edf3actionTb4b4b4.Te6edf3destNumTb4b4b4)
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3Favorite Tff7b72-Tff7b72> Te6edf3favoriteNodeTb4b4b4(Te6edf3actionTb4b4b4.Te6edf3nodeTb4b4b4)
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3Ignore Tff7b72-Tff7b72> Te6edf3ignoreNodeTb4b4b4(Te6edf3actionTb4b4b4.Te6edf3nodeTb4b4b4)
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3Reaction Tff7b72-Tff7b72> Te6edf3sendReactionTb4b4b4(Te6edf3actionTb4b4b4)
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3ImportContact Tff7b72-Tff7b72> Te6edf3importContactTb4b4b4(Te6edf3actionTb4b4b4.Te6edf3contactTb4b4b4)
Tff7b72is Te6edf3ServiceActionTb4b4b4.Te6edf3SendContact Tff7b72-Tff7b72> Te6edf3sendContactTb4b4b4(Te6edf3actionTb4b4b4.Te6edf3contactTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/**
* Imports a manually shared contact.
*
* This function takes a [AdminProtos.SharedContact] proto, marks it as manually verified, sends it for further
* processing, and then handles the import specific logic.
*
* @param contact The [AdminProtos.SharedContact] to be imported.
*/
Tff7b72private Tff7b72fun Td2a8ffimportContactTb4b4b4(Te6edf3contactTb4b4b4: Te6edf3AdminProtosTb4b4b4.Te6edf3SharedContactTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3verifiedContact Tff7b72= Te6edf3contactTb4b4b4.Te6edf3copy Tb4b4b4{ Te6edf3manuallyVerified Tff7b72= Tff7b72true Tb4b4b4}
Te6edf3sendContactTb4b4b4(Te6edf3verifiedContactTb4b4b4)
Te6edf3handleSharedContactImportTb4b4b4(Te6edf3contact Tff7b72= Te6edf3verifiedContactTb4b4b4)
Tb4b4b4}
T8b949e/**
* Sends a shared contact to the radio via [AdminProtos.AdminMessage]
*
* @param contact The contact to send.
*/
Tff7b72private Tff7b72fun Td2a8ffsendContactTb4b4b4(Te6edf3contactTb4b4b4: Te6edf3AdminProtosTb4b4b4.Te6edf3SharedContactTb4b4b4) Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3addContact Tff7b72= Te6edf3contact Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffgetDeviceMetadataTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{ Te6edf3getDeviceMetadataRequest Tff7b72= Tff7b72true Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8fffavoriteNodeTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3isFavoriteTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffremoving node Tffd700${Te6edf3nodeTb4b4b4.Te6edf3numTffd700}Ta5d6ff from favorite listTa5d6ff"Tb4b4b4)
Te6edf3removeFavoriteNode Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3num
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffadding node Tffd700${Te6edf3nodeTb4b4b4.Te6edf3numTffd700}Ta5d6ff to favorite listTa5d6ff"Tb4b4b4)
Te6edf3setFavoriteNode Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3num
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3updateNodeInfoTb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isFavorite Tff7b72= Tff7b72!Te6edf3nodeTb4b4b4.Te6edf3isFavorite Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffignoreNodeTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3isIgnoredTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffremoving node Tffd700${Te6edf3nodeTb4b4b4.Te6edf3numTffd700}Ta5d6ff from ignore listTa5d6ff"Tb4b4b4)
Te6edf3removeIgnoredNode Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3num
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffadding node Tffd700${Te6edf3nodeTb4b4b4.Te6edf3numTffd700}Ta5d6ff to ignore listTa5d6ff"Tb4b4b4)
Te6edf3setIgnoredNode Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3num
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3updateNodeInfoTb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isIgnored Tff7b72= Tff7b72!Te6edf3nodeTb4b4b4.Te6edf3isIgnored Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsendReactionTb4b4b4(Te6edf3reactionTb4b4b4: Te6edf3ServiceActionTb4b4b4.Te6edf3ReactionTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
T8b949e// contactKey: unique contact key filter (channel)+(nodeId)
Tff7b72val Te6edf3channel Tff7b72= Te6edf3reactionTb4b4b4.Te6edf3contactKeyTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3digitToIntTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3destNum Tff7b72= Te6edf3reactionTb4b4b4.Te6edf3contactKeyTb4b4b4.Te6edf3substringTb4b4b4(T79c0ff1Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72=
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(Te6edf3channel Tff7b72= Te6edf3channelTb4b4b4, Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4) Tb4b4b4{
Te6edf3emoji Tff7b72= T79c0ff1
Te6edf3replyId Tff7b72= Te6edf3reactionTb4b4b4.Te6edf3replyId
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APP_VALUE
Te6edf3payload Tff7b72= Te6edf3ByteStringTb4b4b4.Te6edf3copyFromTb4b4b4(Te6edf3reactionTb4b4b4.Te6edf3emojiTb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3rememberReactionTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3copy Tb4b4b4{ Te6edf3from Tff7b72= Te6edf3myNodeNum Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffupdateLastAddressTb4b4b4(Te6edf3deviceAddrTb4b4b4: Tffa657String?Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3currentAddr Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffsetDeviceAddress: received request to change to: Tffd700${Te6edf3deviceAddrTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3deviceAddr Tff7b72!Tff7b72= Te6edf3currentAddrTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(
Ta5d6ff"Ta5d6ffSetDeviceAddress: Device address changed from Tffd700${Te6edf3currentAddrTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff to Tffd700${Te6edf3deviceAddrTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72val Te6edf3currentLabel Tff7b72= Te6edf3currentAddr Tff7b72?: Ta5d6ff"Ta5d6ffnullTa5d6ff"
Tff7b72val Te6edf3nextLabel Tff7b72= Te6edf3deviceAddr Tff7b72?: Ta5d6ff"Ta5d6ffnullTa5d6ff"
Tff7b72val Te6edf3nextTransport Tff7b72= Te6edf3currentTransportTb4b4b4(Te6edf3deviceAddrTb4b4b4)
Te6edf3historyLog Tb4b4b4{ Ta5d6ff"Ta5d6ffdbSwitch request current=Tffd700$Te6edf3currentLabelTa5d6ff next=Tffd700$Te6edf3nextLabelTa5d6ff transportNext=Tffd700$Te6edf3nextTransportTa5d6ff" Tb4b4b4}
Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tff7b72= Te6edf3deviceAddr
Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
T8b949e// Clear only in-memory caches to avoid cross-device bleed
Te6edf3discardNodeDBTb4b4b4(Tb4b4b4)
T8b949e// Switch active on-disk DB to device-specific database
Te6edf3databaseManagerTb4b4b4.Te6edf3switchActiveDatabaseTb4b4b4(Te6edf3deviceAddrTb4b4b4)
Tff7b72val Te6edf3activeAddress Tff7b72= Te6edf3databaseManagerTb4b4b4.Te6edf3currentAddressTb4b4b4.Te6edf3value
Tff7b72val Te6edf3activeLabel Tff7b72= Te6edf3activeAddress Tff7b72?: Ta5d6ff"Ta5d6ffnullTa5d6ff"
Tff7b72val Te6edf3transportLabel Tff7b72= Te6edf3currentTransportTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3meshAddress Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tff7b72?: Ta5d6ff"Ta5d6ffnullTa5d6ff"
Tff7b72val Te6edf3nodeId Tff7b72= Te6edf3myNodeInfoTff7b72?.Te6edf3myNodeNumTff7b72?.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72?: Ta5d6ff"Ta5d6ffunknownTa5d6ff"
Tff7b72val Te6edf3dbSummary Tff7b72=
Ta5d6ff"Ta5d6ffdbSwitch activeAddress=Tffd700$Te6edf3activeLabelTa5d6ff nodeId=Tffd700$Te6edf3nodeIdTa5d6ff transport=Tffd700$Te6edf3transportLabelTa5d6ff addr=Tffd700$Te6edf3meshAddressTa5d6ff"
Te6edf3historyLog Tb4b4b4{ Te6edf3dbSummary Tb4b4b4}
T8b949e// Do not clear packet DB here; messages are per-device and should persist
Te6edf3clearNotificationsTb4b4b4(Tb4b4b4)
T8b949e// Reload nodes from the newly switched database
Te6edf3loadCachedNodeDBTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffSetDeviceAddress: Device address is unchanged, ignoring.Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffclearNotificationsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3serviceNotificationsTb4b4b4.Te6edf3clearNotificationsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3binder Tff7b72=
Tff7b72object Tb4b4b4: T56d364IMeshServiceTb4b4b4.Te6edf3StubTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72override Tff7b72fun Td2a8ffsetDeviceAddressTb4b4b4(Te6edf3deviceAddrTb4b4b4: Tffa657String?Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffPassing through device change to radio service: Tffd700${Te6edf3deviceAddrTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff"Tb4b4b4)
Te6edf3updateLastAddressTb4b4b4(Te6edf3deviceAddrTb4b4b4)
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Te6edf3deviceAddrTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsubscribeReceiverTb4b4b4(Te6edf3packageNameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3receiverNameTb4b4b4: Tffa657StringTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3subscribeReceiverTb4b4b4(Te6edf3receiverNameTb4b4b4, Te6edf3packageNameTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetUpdateStatusTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tff7b72-T79c0ff4
Tff7b72override Tff7b72fun Td2a8ffstartFirmwareUpdateTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetMyNodeInfoTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3MyNodeInfo? Tff7b72= Tff7b72thisTf0883e@MeshService.myNodeInfoTff7b72?.Te6edf3toMyNodeInfoTb4b4b4(Tb4b4b4)
Tff7b72override Tff7b72fun Td2a8ffgetMyIdTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{ Te6edf3myNodeID Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetPacketIdTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{ Te6edf3generatePacketIdTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetOwnerTb4b4b4(Te6edf3userTb4b4b4: Te6edf3MeshUserTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3setOwnerTb4b4b4(
Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3user Tb4b4b4{
Te6edf3id Tff7b72= Te6edf3userTb4b4b4.Te6edf3id
Te6edf3longName Tff7b72= Te6edf3userTb4b4b4.Te6edf3longName
Te6edf3shortName Tff7b72= Te6edf3userTb4b4b4.Te6edf3shortName
Te6edf3isLicensed Tff7b72= Te6edf3userTb4b4b4.Te6edf3isLicensed
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetRemoteOwnerTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72val Te6edf3parsed Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3UserTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3payloadTb4b4b4)
Te6edf3setOwnerTb4b4b4(Te6edf3idTb4b4b4, Te6edf3parsedTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetRemoteOwnerTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{ Te6edf3getOwnerRequest Tff7b72= Tff7b72true Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsendTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3id Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Te6edf3pTb4b4b4.Te6edf3id Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3bytes Tff7b72= Te6edf3pTb4b4b4.Te6edf3bytesTff7b72!!
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(
Ta5d6ff"Ta5d6ffsendData dest=Tffd700${Te6edf3pTb4b4b4.Te6edf3toTffd700}Ta5d6ff, id=Tffd700${Te6edf3pTb4b4b4.Te6edf3idTffd700}Ta5d6ff <- Tffd700${Te6edf3bytesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff bytes (connectionState=Tffd700${Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3dataType Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72throw Te6edf3ExceptionTb4b4b4(Ta5d6ff"Ta5d6ffPort numbers must be non-zero!Ta5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3bytesTb4b4b4.Te6edf3size Tff7b72>Tff7b72= Te6edf3MeshProtosTb4b4b4.Te6edf3ConstantsTb4b4b4.Te6edf3DATA_PAYLOAD_LENTb4b4b4.Te6edf3numberTb4b4b4) Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3ERROR
Tff7b72throw Te6edf3RemoteExceptionTb4b4b4(Ta5d6ff"Ta5d6ffMessage too longTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3QUEUED
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3value Tff7b72=Tff7b72= Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3sendNowTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffError sending message, so enqueueingTa5d6ff"Tb4b4b4)
Te6edf3enqueueForSendingTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3enqueueForSendingTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Te6edf3serviceBroadcastsTb4b4b4.Te6edf3broadcastMessageStatusTb4b4b4(Te6edf3pTb4b4b4)
Te6edf3rememberDataPacketTb4b4b4(Te6edf3pTb4b4b4, Tff7b72falseTb4b4b4)
Te6edf3analyticsTb4b4b4.Te6edf3trackTb4b4b4(Ta5d6ff"Ta5d6ffdata_sendTa5d6ff"Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6ffnum_bytesTa5d6ff"Tb4b4b4, Te6edf3bytesTb4b4b4.Te6edf3sizeTb4b4b4)Tb4b4b4, Te6edf3DataPairTb4b4b4(Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4, Te6edf3pTb4b4b4.Te6edf3dataTypeTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetConfigTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3ByteArray Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72thisTf0883e@MeshService.localConfig.toByteArrayTb4b4b4(Tb4b4b4) Tff7b72?: Tff7b72throw Te6edf3NoDeviceConfigExceptionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetConfigTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3setRemoteConfigTb4b4b4(Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3myNodeNumTb4b4b4, Te6edf3payloadTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetRemoteConfigTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3numTb4b4b4: Tffa657IntTb4b4b4, Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffSetting new radio config!Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3config Tff7b72= Te6edf3ConfigProtosTb4b4b4.Te6edf3ConfigTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3payloadTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3numTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4) Tb4b4b4{ Te6edf3setConfig Tff7b72= Te6edf3config Tb4b4b4}Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3num Tff7b72=Tff7b72= Te6edf3myNodeNumTb4b4b4) Te6edf3setLocalConfigTb4b4b4(Te6edf3configTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetRemoteConfigTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3configTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3config Tff7b72=Tff7b72= Te6edf3AdminProtosTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3ConfigTypeTb4b4b4.Te6edf3SESSIONKEY_CONFIG_VALUETb4b4b4) Tb4b4b4{
Te6edf3getDeviceMetadataRequest Tff7b72= Tff7b72true
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3getConfigRequestValue Tff7b72= Te6edf3config
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetModuleConfigTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3numTb4b4b4: Tffa657IntTb4b4b4, Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffSetting new module config!Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3config Tff7b72= Te6edf3ModuleConfigProtosTb4b4b4.Te6edf3ModuleConfigTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3payloadTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3numTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4) Tb4b4b4{ Te6edf3setModuleConfig Tff7b72= Te6edf3config Tb4b4b4}Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3num Tff7b72=Tff7b72= Te6edf3myNodeNumTb4b4b4) Te6edf3setLocalModuleConfigTb4b4b4(Te6edf3configTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetModuleConfigTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3configTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3getModuleConfigRequestValue Tff7b72= Te6edf3config
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetRingtoneTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3ringtoneTb4b4b4: Tffa657StringTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3setRingtoneMessage Tff7b72= Te6edf3ringtone Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetRingtoneTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3getRingtoneRequest Tff7b72= Tff7b72true
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetCannedMessagesTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3messagesTb4b4b4: Tffa657StringTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3setCannedMessageModuleMessages Tff7b72= Te6edf3messages Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetCannedMessagesTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3getCannedMessageModuleMessagesRequest Tff7b72= Tff7b72true
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetChannelTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArray?Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3setRemoteChannelTb4b4b4(Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3myNodeNumTb4b4b4, Te6edf3payloadTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetRemoteChannelTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3numTb4b4b4: Tffa657IntTb4b4b4, Te6edf3payloadTb4b4b4: Te6edf3ByteArray?Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72val Te6edf3channel Tff7b72= Te6edf3ChannelProtosTb4b4b4.Te6edf3ChannelTb4b4b4.Te6edf3parseFromTb4b4b4(Te6edf3payloadTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3numTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4) Tb4b4b4{ Te6edf3setChannel Tff7b72= Te6edf3channel Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetRemoteChannelTb4b4b4(Te6edf3idTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3indexTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3idTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3getChannelRequest Tff7b72= Te6edf3index Tff7b72+ T79c0ff1
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffbeginEditSettingsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3beginEditSettings Tff7b72= Tff7b72true Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffcommitEditSettingsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3commitEditSettings Tff7b72= Tff7b72true Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetChannelSetTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3ByteArray Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{ Tff7b72thisTf0883e@MeshService.channelSet.toByteArrayTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetNodesTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3MutableListTff7b72<Te6edf3NodeInfoTff7b72> Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72val Te6edf3r Tff7b72= Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3valuesTb4b4b4.Te6edf3map Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3toNodeInfoTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4.Te6edf3toMutableListTb4b4b4(Tb4b4b4)
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffin getOnline, count=Tffd700${Te6edf3rTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff"Tb4b4b4)
Te6edf3r
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffconnectionStateTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72val Te6edf3r Tff7b72= Te6edf3connectionStateHolderTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3value
Te6edf3TimberTb4b4b4.Te6edf3iTb4b4b4(Ta5d6ff"Ta5d6ffin connectionState=Tffd700$Te6edf3rTa5d6ff"Tb4b4b4)
Te6edf3rTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffstartProvideLocationTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{ Te6edf3startLocationRequestsTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffstopProvideLocationTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{ Te6edf3stopLocationRequestsTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffremoveByNodenumTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3nodeDBbyNodeNumTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3nodeNumTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3newMeshPacketToTb4b4b4(Te6edf3myNodeNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{ Te6edf3removeByNodenum Tff7b72= Te6edf3nodeNum Tb4b4b4}Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestUserInfoTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72!Tff7b72= Te6edf3myNodeNumTb4b4b4) Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(Te6edf3channel Tff7b72= Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3destNumTff7b72]Tff7b72?.Te6edf3channel Tff7b72?: T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3NODEINFO_APP_VALUE
Te6edf3wantResponse Tff7b72= Tff7b72true
Te6edf3payload Tff7b72= Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3myNodeNumTff7b72]Tff7b72!!Tb4b4b4.Te6edf3userTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestPositionTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3positionTb4b4b4: Te6edf3PositionTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72!Tff7b72= Te6edf3myNodeNumTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3provideLocation Tff7b72= Te6edf3meshPrefsTb4b4b4.Te6edf3shouldProvideNodeLocationTb4b4b4(Te6edf3myNodeNumTb4b4b4)
Tff7b72val Te6edf3currentPosition Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3provideLocation Tff7b72&Tff7b72& Te6edf3positionTb4b4b4.Te6edf3isValidTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3position
Tff7b72else Tff7b72-Tff7b72> Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3myNodeNumTff7b72]Tff7b72?.Te6edf3positionTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3PositionTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isValidTb4b4b4(Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3currentPosition Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffPosition request skipped - no valid position availableTa5d6ff"Tb4b4b4)
Tff7b72returnTf0883e@toRemoteExceptions
Tb4b4b4}
Tff7b72val Te6edf3meshPosition Tff7b72= Te6edf3position Tb4b4b4{
Te6edf3latitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3currentPositionTb4b4b4.Te6edf3latitudeTb4b4b4)
Te6edf3longitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3currentPositionTb4b4b4.Te6edf3longitudeTb4b4b4)
Te6edf3altitude Tff7b72= Te6edf3currentPositionTb4b4b4.Te6edf3altitude
Te6edf3time Tff7b72= Te6edf3currentSecondTb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(
Te6edf3channel Tff7b72= Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3destNumTff7b72]Tff7b72?.Te6edf3channel Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3POSITION_APP_VALUE
Te6edf3payload Tff7b72= Te6edf3meshPositionTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Te6edf3wantResponse Tff7b72= Tff7b72true
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsetFixedPositionTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3positionTb4b4b4: Te6edf3PositionTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Tff7b72val Te6edf3pos Tff7b72= Te6edf3position Tb4b4b4{
Te6edf3latitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3positionTb4b4b4.Te6edf3latitudeTb4b4b4)
Te6edf3longitudeI Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3positionTb4b4b4.Te6edf3longitudeTb4b4b4)
Te6edf3altitude Tff7b72= Te6edf3positionTb4b4b4.Te6edf3altitude
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacket Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3position Tff7b72!Tff7b72= Te6edf3PositionTb4b4b4(T79c0ff0.0Tb4b4b4, T79c0ff0.0Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3setFixedPosition Tff7b72= Te6edf3pos
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3removeFixedPosition Tff7b72= Tff7b72true
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3updateNodeInfoTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3setPositionTb4b4b4(Te6edf3posTb4b4b4, Te6edf3currentSecondTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestTracerouteTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3tracerouteStartTimesTff7b72[Te6edf3requestIdTff7b72] Tff7b72= Te6edf3SystemTb4b4b4.Te6edf3currentTimeMillisTb4b4b4(Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildMeshPacketTb4b4b4(
Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3destNumTff7b72]Tff7b72?.Te6edf3channel Tff7b72?: T79c0ff0Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3portnumValue Tff7b72= Te6edf3PortnumsTb4b4b4.Te6edf3PortNumTb4b4b4.Te6edf3TRACEROUTE_APP_VALUE
Te6edf3wantResponse Tff7b72= Tff7b72true
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestShutdownTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4) Tb4b4b4{ Te6edf3shutdownSeconds Tff7b72= T79c0ff5 Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestRebootTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4) Tb4b4b4{ Te6edf3rebootSeconds Tff7b72= T79c0ff5 Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestFactoryResetTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4) Tb4b4b4{ Te6edf3factoryResetDevice Tff7b72= T79c0ff1 Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffrequestNodedbResetTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3preserveFavoritesTb4b4b4: Tffa657BooleanTb4b4b4) Tff7b72=
Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4) Tb4b4b4{ Te6edf3nodedbReset Tff7b72= Te6edf3preserveFavorites Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetDeviceConnectionStatusTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3toRemoteExceptions Tb4b4b4{
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3newMeshPacketToTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3buildAdminPacketTb4b4b4(Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3getDeviceConnectionStatusRequest Tff7b72= Tff7b72true
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.53s